c++中拷贝构造函数,浅拷贝和深拷贝的区别,以及移动构造函数总结
一、构造函数、浅拷贝和深拷贝
在C++提供了一种特殊的构造函数,称为拷贝构造函数。拷贝构造函数具有一般构造函数的所有特性,其作用是使用一个已经存在的对象(由拷贝构造函数的参数指定的对象)去初始化一个新的同类对象,即完成本类对象的复制。程序员如果没有定义拷贝构造函数,系统会自动生成一个默认的拷贝构造函数,其功能是把已存在的每个数据成员都复制到新对象中。程序员定义拷贝构造函数时,一般形式:
类名(类名 & 对象)
{
}
拷贝构造函数在三种情况下会被自动调用
(1)用一个对象去初始化一个同类的对象 XX B(A)
(2) XX aa = a,当一个新对象被定义的时候,即便这个时候是使用了'='运算符,它真实调用的是初始化函数copy constructor,而不是调用copy assignment operator去进行赋值操作。;
(3)如果函数的形参是对象,进行形参和实参结合时,调用拷贝构造函数。f(A);
(4)如果函数的返回值是对象,返回主调函数时,调用拷贝构造函数。 XX B=g();
其中默认的拷贝构造函数是浅拷贝。当类的数据成员有指针类型是,假设同类对象A初始化B,A和B对象使用同一内存区域。在撤销对象时,导致对这一内存的两次释放,也就是说浅层复制:只复制指向对象的指针,而不复制引用对象本身。这时候要求程序员编制拷贝构造函数,使对象B的指针指向另外的内存区域,这叫深拷贝,深层复制:复制引用对象本身。
二、移动构造函数
右值引用,临时值,如果是临时值,不调用深拷贝,而是移动构造函数(move construct),来提升性能。
#include<iostream> using namespace std; class Test{ public: Test() :x(0) { cout << "构造函数 this = " << this << endl; } Test(int x) :x(x) { cout << "构造函数 this = " << this << endl; } Test(const Test& another) :x(another.x) { cout << "拷贝构造函数 this = " << this << " from " << &another << endl; } Test(const Test&& another) : x(another.x) { cout << "移动构造函数 this = " << this<< " from " << &another << endl; } ~Test() { cout << "析构函数 this = " << this << endl; } friend ostream& operator<<(ostream& out, const Test &t); private: int x; }; //运算符重载 ostream& operator<<(ostream& out, const Test &t){ out << "&t = " << &t << ",x = " << t.x; return out; } Test maketest() { Test x(4); cout << "hell" << endl; return x; } int main() { //测试拷贝构造函数 Test test(3); cout << test << endl; Test test2(test); cout << test2 << endl; cout << endl; //测试移动构造函数 Test first = maketest();//有一个临时对象, cout << first << endl; cout << endl; system("pause"); }
//测试移动构造函数1 Test first = maketest();//有一个临时对象, /* 测试1结果分析:正常情况下直接调用拷贝构造函数,如果定义了移动构造函数, 则直接调用移动构造函数。 */ //测试移动构造函数2 //Test first;//有一个临时对象, //first = maketest(); /* 测试2结果分析:正常情况下,是调用拷贝构造函数,然后调用赋值构造函数, 但如果定义了移动构造函数,就是调用移动构造函数,然后调用赋值构造函数。 */
输出结果:
如果没有移动构造函数,可以看结果:
用的拷贝构造函数,但拷贝构造函数有性能损失,可以参考
https://blog.csdn.net/weiqing00/article/details/80929788