这个题目是参考别人面经的一道题,顺着这个问题研究了一下拷贝构造函数。拷贝构造函数简单点理解就是通过一个已有的对象去构造一个新的对象。
class Foo {
public:
Foo(); //默认构造函数
Foo(const Foo&); //拷贝构造函数
}
拷贝构造函数的第一个参数必须是引用类型,一般情况下我们在拷贝构造函数也不会尝试改变传进来的参数,所以加const。参数不能是值传递,具体原因可以看看【C++】类的拷贝构造函数参数为什么一定要是引用类型?
拷贝构造函数的作用和用途?
拷贝构造函数一般用于以下三种情况:
1.当用类的一个对象去初始化该类的另外一个对象时。
2.如果函数的形参是类的对象,调用函数时,是值传递。(引用传递并不调用拷贝构造函数)
3.如果函数的返回值是类的对象,函数执行完成时会返回调用者时。
深拷贝和浅拷贝的理解
对于普通成员,浅拷贝和深拷贝并没有区别。主要区别在于对于指针的拷贝。假设有一个A对象存在一个a指针,指向D内存。用A对象去初始化一个新的对象B,如果是浅拷贝,那么只会拷贝指针b=a,它们都指向D内存区域。如果是深拷贝,不仅拷贝指针b=a,还会申请一块新的内存空间E,原来的a指向D,新的b指向E。
什么时候需要自定义拷贝构造函数?
前面提到浅拷贝和深拷贝的区别在于会不会复制新的内存空间(前提是类中存在指针类成员变量)。如果是浅拷贝的状态下,析构A对象,必然会释放D内存;析构B对象时,指针b同样指向D内存,此时D内存早已经被释放了。就出现了同一内存空间被释放两次的情况,系统就会报错。
类定义时,如果没有显式定义拷贝构造函数,就会调用默认拷贝构造函数,对应的是浅拷贝。正确的方法是定义一个显示的拷贝构造函数实现深拷贝。
总结:当类存在指针类成员变量时,默认拷贝构造函数是浅拷贝,会导致二次析构问题,所以要自定义拷贝构造函数。
《C++ Primer中文版》