复制构造函数必须加const的情形、编译器优化的情形和调用移动构造函数的情形

以下情况都会调用拷贝构造函数:
① 程序中需要新建立一个对象,并用另一个同类的对象对它初始化。
② 当函数的参数为类的对象时。在调用函数时需要将实参对象传递给形参,也就是需要建立一个实参的拷贝,这就是按实参复制一个形参,系统是通过调用复制构造函数来实现的,这样能保证形参具有和实参完全相同的值。
③ 函数的返回值是类的对象。在函数调用完毕将返回值带回函数调用处时,需要将函数中的对象复制一个临时对象并传给该函数的调用处。
注意:对已经初始化过的对象直接赋值,不会调用复制构造函数
下面来上实例:

#include <iostream>

using namespace std;
class Point
{
    int x,y;
public:
    Point(){cout<<"default construct"<<endl;}
    Point(int a,int b):x(a),y(b){cout<<"construct"<<endl;}
    Point(/*注意这里不加const是正确的*/Point &p):x(p.x),y(p.y){cout<<"copy"<<endl;}
};
Point fun(Point p)
{
    return p;
}
int main()
{
    Point a(1,2);
    Point b;
    b=fun(a);
    return 0;
}

在这里插入图片描述
这和一开始的理论吻合,第一次形实结合时调用了复制构造函数,第二次在返回时先调用复制构造函数开辟了一块临时空间储存返回的对象,然后把临时对象赋值给b。共调用2次。

#include <iostream>

using namespace std;
class Point
{
    int x, y;
public:
    Point() { cout << "default construct" << endl; }
    Point(int a, int b) :x(a), y(b) { cout << "construct" << endl; }
    Point( const/*此程序必须加const*/ Point& p) :x(p.x), y(p.y) { cout << "copy" << endl; }
};
Point fun(Point p)
{
    return p;
}
int main()
{
    Point a(1, 2);
    Point b=fun(a);//直接初始化
    return 0;
}

在这里插入图片描述
复制构造函数调用了两次,第一次是形实结合时,第二次是用返回值初始化b时,为什么定义复制构造函数必须加const呢?因为返回值是一个常量,该常量作为复制构造函数的参数,而常量不可以作为变量的引用。
那么问题又来了,为什么函数的返回值是类的对象,却没有调用复制构造函数呢?
答案是:编译器自动进行了优化,避免多调用一次复制构造函数。

#include <iostream>

using namespace std;
class Point
{
    int x, y;
public:
    Point() { cout << "default construct" << endl; }
    Point(Point&& p) { cout << "move" << endl; }
    Point(int a, int b) :x(a), y(b) { cout << "construct" << endl; }
    Point( /*不需要const*/Point& p) :x(p.x), y(p.y) { cout << "copy" << endl; }
};
Point fun(Point p)
{
    return p;
}
int main()
{
    Point a(1, 2);
    Point b=fun(a);
    return 0;
}

在这里插入图片描述
变成只调用一次复制构造函数了,怎么回事?
先说移动构造函数:移动语义可以将资源(堆、系统对象等)通过浅拷贝方式从一个对象转移到另一个对象,这样能减少不必要的临时对象的创建、拷贝以及销毁,可以大幅度提高C++应用程序的性能,消除临时对象的维护(创建和销毁)对性能的影响。
在此处直接把形参的地址给了b,调的是移动构造函数。因此也不用const。
再推荐一篇讲编译器优化的博客:https://blog.csdn.net/qq_36482119/article/details/101039634
讲移动构造函数的博客
https://blog.csdn.net/weiqing00/article/details/80929788

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值