C++学习笔记07-复制构造的坑

复制构造函数

复制构造函数专门是用一个对象完成另外一个【声明的】对象的初始化
如下面的代码所示

#include <iostream>

using namespace std;
class Test
{
	private :
		int height;
    public :
        Test(int height_) : height(height_)
        {
            cout << "调用了普通构造函数噢\n";
        }
//    private :
        Test(const Test & t) : height(t.height)
        {
            cout<< "调用了复制构造函数噢\n";
        }
    public :
        Test & operator=(const Test & t)
        {
            if(this==&t)
                return *this;
            cout << "调用了赋值运算符噢" << endl;
            height = t.height;
            return *this;
        }
};
int main()
{
	Test obj1(188);
	Test obj2 = obj1;
	obj2 = obj1;//不是【声明】,因此此行属于调用了赋值运算符!!!
	Test obj3 = Test(188);
    cout << "-----------------------\n";
    obj3 = 190;
    Test obj4 = 190;//原因同Test obj3 = Test(188);
}

对Test obj1(188);解释:

就是使用了普通构造函数

对Test obj2 = obj1;解释:

就是用复制构造函数,在声明的时候用对象初始化另外一个对象
复制构造函数负责先创建一个对象,再把=右边的用来初始化声明的对象

对obj2 = obj1;解释

由于不是声明时创建对象,只是普通的对象赋值,符合赋值运算符的调用条件,
因此调用的是赋值运算符

对Test obj3 = Test(188);解释

原来是:把一个声明的对象先创建,并在声明时用Test(188)初始化obj3,所以调用复制构造函数,
但是编译器优化了该步骤,不需要频繁的调用复制构造函数和赋值运算符
直接就给你一步到位,完成了对象的初始化,
普通构造函数创建出来的就是你声明的对象,相当于Test obj3(188);
从而使得看起来不需要复制构造函数的样子,
但是,如果你私有了复制构造函数,
就不会为你做这个只用普通构造函数初始化对象的优化,从而需要复制构造函数
但是你又私有了复制构造函数,类外不能用,因此编译报错,在上下文中私有化了复制构造函数

对obj3 = 190;的解释

编译器发现190可以直接转化为类对象,于是调用Test(int),又发现可以优化
情况又和Test obj3 = Test(188);一样了

输出结果

在这里插入图片描述

解开了private注释后的编译报错

在这里插入图片描述

参考文章:

C++的一大误区——深入解释直接初始化与复制初始化的区别
C++ Primer 原文理论支持的编译器优化:442页,第五版中文版
在这里插入图片描述

复制构造函数调用条件

①声明并初始化(非引用)对象的时候调用
②对象按值传递和按值返回对象
③花括号列表初始化数组或者聚合类成员
④某些类类型还会对他们所分配的对象进行拷贝初始化,,例如我们初始化标准容器或
是调用其insert或push成员,容器回对其元素进行拷贝初始化,与之相对,用emplace成员
创建的元素都进行直接初始化,
注:
②的情况都和①是完全一样的,返回值相当于一个匿名的变量,形参就是相当于是声明了对象

写在最后

纸上觉来终觉浅,听别人说总是印象不深刻,必须要自己多手打代码验证一下

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿维的博客日记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值