【面向对象】构造函数与析构函数详解

news2024/10/9 20:30:30

构造函数与析构函数详解

在这里插入图片描述



😊点此到文末惊喜↩︎

构造函数

类型

  1. 默认构造函数(缺省构造函数)
    • 一个类中只能出现一个默认构造函数
    • 在调用时,不需要传入实参。因为默认构造函数通常是无参的或所有形参都有缺省值
    • 使用默认构造函数的时候创建对象不能后面带有括号
    • 编译器自动生成non-trivial的构造函数有四种情况,其他情况就算编译器产生了默认构造函数也没有实质作用。
      • 类中有类:类A含有类B的对象作为成员,并且类B显式定义了默认构造函数,则定义类A对象的时候编译器会产生一个默认构造函数,并在这个默认构造函数中提供了调用类B构造函数的代码。
      • 类继承类:类B继承于类A,且类A显式定义了构造函数,那么在生成类B对象的过程中编译器同样会产生一个默认构造函数,在这个构造函数中提供调用基类A构造函数的代码
      • 含虚函数类:某个类含有虚函数,那么编译器会自动产生一个默认构造函数以提供虚表指针相关的初始化操作
      • 虚继承基类:一个类虚继承于其他类,那么同样的编译器会为该类产生默认的构造函数。
  2. 初始化构造函数(有参构造函数)
    • 在创建对象时,使用实参为对象的成员属性赋值,由编译器自动调用
  3. 复制 / 拷贝构造函数
    • 若没有显示定义复制构造函数,则系统会默认创建一个复制构造函数,当类中有指针成员时,由系统默认创建的复制构造函数会存在“浅拷贝”的风险,因此必须显示定义复制构造函数。
    • 复制构造函数参数为类对象本身的引用,根据调用对象进行深拷贝构建实参对象
    • 被调用的三种情况
      • 对象用于给其他对象进行赋值初始化
      • 对象作为函数形参
      • 对象作为函数返回值,实质是返回值对象作为类复制构造函数实参而调用
      //  1. 对象的赋值初始化
      Complex c2(c1);
      Complex c2 = c1;
      // 2. 函数形参
      void Function(Complex  c){
      	 ...
      }
      	// 可以使用const & :确保实参的值不会改变,并避免复制构造函数带来的深拷贝开销
      void Function(const Complex & c){
      	 
      }
      //3. 函数返回值
      Complex Func() {
          Complex  a(4);
          return a;
      }
      
  4. 移动构造函数
    • 临时对象转移内存所属权时调用,使用右值引用作为参数。
    	class Integer {
    	private:
    	    int* m_ptr;
    	public:
    		Integer(Integer&& source)// 注意形参是右值引用
    		  : m_ptr(source.m_ptr) {
    		    source.m_ptr= nullptr;
    		    cout << "Call Integer(Integer&& source)移动" << endl;
    		}
    	};
    	int main(int argc, char const* argv[]) {
    	    Integer a;
    	    Integer b(std::move(a));// 将a转换成右值引用
    	    return 0;
    	}
    
  5. 委托构造函数
    • 构造函数可以在同一个类中一个构造函数调用另一个构造函数,从而达到简化代码的目的。
    #include <iostream>
    class Base 
    {
    public:
    	int value1;
    	int value2;
    	Base()    //目标构造函数
    	{
    		value1 = 1;
    	}
    	Base(int value) : Base()  //委托构造函数
    	{ // 委托 Base() 构造函数
    		value2 = value;
    	}
    };
    void EntrustedConstruction()
    {
    	Base b(2);  //首先调用Base(int value) : Base() 毫无疑问
        //然后会走到base()中,先给value1复制,然后走到Base(int value) : Base() ,给value2赋值
    	std::cout << b.value1 << std::endl;
    	std::cout << b.value2 << std::endl;
    }
    
    
  6. 转换构造函数
    • 只有一个参数的构造函数,而且该参数又不是本类的const引用
    	#include <iostream>
    using namespace std;
    
    class Student{
    public:
        //1. 默认构造函数,没有参数或形参具有缺省值
        Student(int i=2){
            this->age = 20;
            this->num = 1000;
        };  
        // 2. 初始化构造函数,有参数和参数列表
        Student(int a, int n):age(a), num(n){};
        // 3. 拷贝构造函数,参数是对象
        Student(const Student& s){
            this->age = s.age;
            this->num = s.num;
        };
        // 4. 移动构造函数,参数是右值引用
        Student(const Student&& s){
            this->age = s.age;
            this->num = s.num;
        }; 
        
        // 3. 转换构造函数,形参是其他类型变量,且只有一个形参
        Student(int r){   //
            this->age = r;
    		this->num = 1002;
        };
        ~Student(){}
    public:
        int age;
        int num;
    };
    


少年,我观你骨骼清奇,颖悟绝伦,必成人中龙凤。
秘籍(点击图中书籍)·有缘·赠予你


🚩点此跳转到首行↩︎

参考博客

  1. C++构造函数之默认构造函数
  2. C++默认构造函数——深入理解
  3. 对C++默认构造函数的一点重要说明
  4. 拷贝构造函数
  5. 委托构造函数详解,小白也可以看懂
  6. 待定引用
  7. 待定引用
  8. 待定引用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/190931.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

射频信号探测器制作

射频信号探测器制作一、元件要求二、芯片参数三、原理剖析四、实验思路五、实物展示、使用六、个人总结一、元件要求 CD4001&#xff0c;是四2输入或非门。或非门的逻辑关系特点是只有当输入端全部为低电平时&#xff0c;输出端为高电平状态&#xff1b;在其余输入情况下&…

TCP-IP协议基础知识

1、简介 tcp/ip&#xff1a;通信协议的统称&#xff0c;是IP,ICMP,TCP,UDP,HTTP,TELNET,SNMP,SMTP等协议的集合 TCP/IP和OSI的关系 OSI属于ISO&#xff08;国际化标准组织&#xff09;制定的通信系统标准&#xff0c;但是并没有普及&#xff1b;TCP/IP是非ISO制定的某种国际…

详谈ORB-SLAM2的局部建图线程LocalMapping

ORB-SLAM2的局部建图线程LocalMapping分为5个步骤&#xff0c;非常简单。当得到缓冲队列里的关键帧&#xff0c;第一步处理当前关键帧的地图点关系等&#xff1b;第二步判断地图点是否为新创建&#xff0c;如果是那就进入测试&#xff0c;测试地图点的好坏&#xff0c;如果不好…

【关于Linux中----信号】

文章目录一、信号入门1.1 信号概念1.2 用 kill-l命令查看信号列表1.3 信号处理常见方式预览二、产生信号2.1 通过终端按键产生信号2.2 由于程序中存在异常产生信号2.3 系统接口调用产生信号2.4 软件条件产生信号三、阻塞信号3.1 信号相关常见概念补充3.2 在内核中的表示3.3 sig…

编码技巧——JDK版本切换/JDK7和JDK6下的文件输入输入

最近有使用低版本JDK实现文件输入输出的需求&#xff0c;主要是妹子计算机专业考研复试上级算法题&#xff0c;输入输入依赖文件而非纯算法代码&#xff0c;并且IDE一般使用JDK8以下的SDK&#xff0c;导致一些JDK8的API不适用&#xff1b;较早版本的JDK API代码是操作一大堆的缓…

jenkins部署过程

Jenkins 安装 示例服务器为 阿里云 CentOS 服务器。安全组中增加 8080 端口 Jenkins 默认占用 Jenkins 安装大体分两种方式&#xff0c;一种使用 Docker 另一种则是直接安装&#xff0c;示例选择后者。不管使用哪种方式安装&#xff0c;最终使用层面都是一样的。 Linux安装过…

Linux下源码安装nginx

一 安装步骤 nginx在linux下的源码安装&#xff0c;步骤还是比较简单的&#xff0c;主要分为以下 1. 下载安装包&#xff0c;这里选择&#xff1a;nginx-1.18.0.tar.gz 下载地址&#xff1a;http://nginx.org/en/download.html 2. 安装前置环境&#xff1a; yum install -y…

苹果手机字体大小怎么设置?简单实用,轻松学会

使用苹果手机的时候&#xff0c;发现苹果手机的字体看起来不是很舒服&#xff0c;想要将字体调大一点&#xff0c;却不知道怎么办。苹果手机字体大小怎么设置&#xff1f;其实方法很简单&#xff0c;今天小编就来具体的讲一下调整苹果手机字体大小的方法。 苹果手机字体大小怎么…

智能工厂中的设备如何实现远程监控和故障报警

智能工厂是在数字化工厂内&#xff0c;利用物联网技术和云计算计算加强设备信息管理水平&#xff0c;提高生产过程可控性、减少生产线人工干预&#xff0c;保证安全稳定的生产节奏&#xff0c;助力构建高效、节能、绿色、舒适、安全的工厂。 物通博联推出的智能工厂设备物联网…

C语言及算法设计课程实验四:选择结构程序设计

C语言及算法设计课程实验四&#xff1a;选择结构程序设计一、实验目的二、实验内容2.1、根据x的分段函数求对于的y值2.2、求小于1000正数的平方根2.3、百分制等级输出2.4、四个整数的顺序输出三、实验步骤3.1、选择结构程序设计实验题目1&#xff1a;根据x的分段函数求对于的y值…

四、GStreamer基础

本章介绍GStreamer的基本概念。理解这些概念对于阅读本指南的其他任何内容都是很重要的&#xff0c;它们都假定理解了这些基本概念。 元素 元素是GStreamer中最重要的一类对象。你通常会创建一个链接在一起的元素链&#xff0c;并让数据在这个元素链中流动。元素有一个特定的…

运动耳机有必要买吗、口碑最好的运动耳机品牌排行

冬天绝对是个减肥的好季节&#xff0c;因为这个季节天气比较冷&#xff0c;我们在运动过程中消耗的热量也就会更多&#xff0c;因此选择一款不错的运动耳机来用坚持就显得尤为重要了。这款运动耳机要能稳定在耳朵上&#xff0c;还要具备防水功能&#xff0c;同时音质上也要有保…

gd32f103vbt6 串口OTA升级-问题记录

今天研究了一下gd32单片机串口OTA升级的事情。我感觉ota的唯一好处就是不用调试器就可以下载&#xff08;更新&#xff09;单片机应用程序。(但是需要232串口&#xff0c;OTA程序我是使用stlink下载的&#xff01;&#xff01;) 可能有些同学要问&#xff0c;32的单片机本身就…

【综合】数字IC设计需要考虑的时序参数;Race Hazard;同步系统时序要求;建立时间、保持时间;偏斜;抖动;毛刺、竞争冒险;亚稳态

【综合】数字IC设计需要考虑的时序参数&#xff1b;Race Hazard&#xff1b;同步系统时序要求&#xff1b;建立时间、保持时间&#xff1b;偏斜&#xff1b;抖动&#xff1b;毛刺、竞争冒险&#xff1b;亚稳态数字设计时需要考虑的时序参数传播延迟 propagation delay, 上升时间…

十一、树结构的实际应用—堆排序

1、基本介绍 堆排序是利用堆这种数据结构而设计的一种排序算法&#xff0c;堆排序是一种选择排序&#xff0c;它的最好最坏平均时间复杂度均为O(n\log n) 。也不是稳定排序。堆是具有以下性质的完全二叉树&#xff1a;每个节点的值都大于或等于其左右孩子节点的值&#xff0c;…

云音乐实现注册功能

1. 新建web项目 Shop_SM2. 复制Shop资源和相关代码&#xff0c;实现注册功能回顾当前配置下的加载顺序1.MyBatis的主配置文件mybatis-config.xml &#xff08;在根目录下&#xff09;和 工具类MyBatisUtil&#xff08;注意总配置文件的路径&#xff09;2.实体类&#xff08;Use…

docker篇---pycharm连接docker,使用docker环境

pycharm连接docker&#xff0c;使用docker环境一、生成镜像和容器1.1 创建容器&#xff0c;需要加端口映射1.2 进入容器1.3 设置root密码&#xff0c;后续登录会用到1.4 修改配置文件1.5 重启ssh服务1.5 本机连接ssh二、pycharm连接docker2.1 允许远程客户端连接2.2 pycharm配置…

线程互斥与同步--Linux

文章目录线程互斥的概念与意义互斥的原理--原子性关于售票模拟的互斥应用死锁问题线程同步的概念与意义条件变量实现同步生产者消费者模型--互斥与同步基于阻塞队列的生产者消费者模型基于环形队列的生产者消费者模型POSIX信号量线程池线程安全下的单例模式总结线程互斥的概念与…

OMS标准 第二卷 主要通讯

版本4.1.2/2016-12-16 发布 1 引言 1.1 概述 本部分描述了从设备&#xff08;仪表或执行器或断路器&#xff09;和&#xff08;固定的&#xff0c;通常由市电供电的&#xff09;主设备&#xff08;网关或其他通信单元&#xff09;之间有线和无线通信的最低开放式计量系统要…

1. Mybatis 入门

文章目录1. Mybatis 简介2. Mybatis 快速入门3. 使用 idea 写 SQL4. Mapper 代理开发5. MyBatis 核心配置文件1. Mybatis 简介 MyBatis 是一款优秀的持久层框架&#xff0c;用于简化 JDBC 开发。 官方文档&#xff1a;https://mybatis.org/mybatis-3/zh/index.html 持久层&am…