C++中的拷贝构造函数是一种特殊的构造函数,只有在一个对象去初始化另一个对象时 ,会执行拷贝构造
拷贝构造函数的特征
-
函数格式:拷贝构造函数的参数是同类的一个引用对象。
:ClassName(ClassName& other);
-
默认拷贝构造函数:如果没有显式定义拷贝构造函数,编译器会自动生成一个默认的拷贝构造函数,执行成员逐个复制(浅拷贝)。
-
浅拷贝 vs. 深拷贝:
- 浅拷贝:默认拷贝构造函数逐个复制成员,对于指针成员,只复制指针的地址而不复制其指向的数据。
- 深拷贝:自定义拷贝构造函数时,可以实现深拷贝,即为指针成员分配新的内存并复制其指向的数据,避免不同对象之间共享相同的内存。
浅拷贝实例:
#include<iostream>
using namespace std;
class AA
{
public:
int a;
public:
AA()
{
cout << "AAAA" << endl;
}
AA(AA& ra)
{
this->a=ra.a;//this->a是当前对象的成员变量a,而ra.a是函数的参数
//表达式的含义是将 ra 的成员变量 a 的值赋给当前对象的成员变量 a,
//从而实现当前对象对 ra 对象的成员变量 a 的复制。
cout << "COPY" << endl;
}
public:
void show()
{
cout << a << endl;
}
};
int main()
{
AA aa;
aa.a = 100;
aa.show();
cout << "------" << endl;
AA bb = aa;
bb.show();
cout << "------" << endl;
AA cc ;
cc = aa;//赋值不会进行拷贝构造
cc.show();
cout << "------" << endl;
AA dd(aa);
dd.show();
return 0;
}
深拷贝实例:
#include<iostream>
using namespace std;
class AA
{
public:
int* a;
AA()
{
a = new int(100);
}
AA(AA& ra)
{
this->a = new int(*ra.a);//深拷贝
}
public:
~AA()
{
delete a;
a = NULL;
}
public:
void show()
{
cout << *a << endl;
}
};
//浅拷贝 将源对象中成员变量的值赋值给目标对象的成员变量
//如果对象成员变量有指针指向堆区 在析构函数中释放 可能会造成二次释放
//默认的拷贝构造是浅拷贝 注意
//深拷贝 先给目标对象成员指针变量开辟一块空间
//再将源对象指针成员所指向空间的值赋值给开辟好的空间
int main()
{
AA aa;
aa.show();
AA bb = aa;//由于是由aa对bb初始化 所以须执行拷贝构造函数
/*所以解决方法就是在添加一个浅拷贝函数 在重新申请一块空间赋值为原来的值
从而在析构释放的时候能正常释放*/
bb.show();
return 0;
}
注:
- 拷贝构造函数 只有一个参数 参数的类型是本类的引用的构造函数
- 拷贝构造函数也有默认的
- 默认拷贝构造函数执行的是浅拷贝(shallow copy), 即简单地将原对象的每一个非静态成员变量的值复制到新对象中
- 一个对象去初始化另一个对象时 会执行拷贝构造