- 在有指针的情况下,浅拷贝只是增加了一个指针指向已经存在的内存,而深拷贝就是增加一个指针并且申请一个新的内存(在堆内存中)。
- 可以理解为深拷贝是建了一个一模一样的副本,拷贝后共有两个实体对象。而浅拷贝只是一个链接,链接的目标还是原来的对象,实体对象数目还是一个。
- 采用深拷贝的情况下,释放内存的时候就不会出现在浅拷贝时重复释放同一内存的错误。
- 默认生成的拷贝构造函数是浅拷贝,对任何一个对象的改变都会影响到另一个对象。
- 深拷贝典型函数:
class String
{
public:
String(const String &other); //拷贝构造函数
private:
char *m_data; //用于保存字符串
};
String(const String &other)
{
int length = strlen(other.m_data);
m_data = new char[length + 1];
strcpy(m_data, other.m_data);
}
-
浅拷贝典型函数:
- `
class A
{
public:
A() // 构造函数,p指向堆中分配的一空间
{
m_data = new char(100);
printf(“默认构造函数\n”);
}
~A() // 析构函数,释放动态分配的空间
{
if(m_data != NULL)
{
delete m_data;
m_data = NULL;
printf(“析构函数\n”);
}
}
private:
char *m_data; // 一指针成员
};
int main()
{
A a;
A b(a); // 复制对象
return 0;
}
` - `
- 定义拷贝构造函数是一种良好的编程风格,它可以阻止编译器形成默认的拷贝构造函数,提高源码效率。
- 什么时候使用:
- 在某些状况下,类内成员变量需要动态开辟堆内存,如果实行位拷贝,也就是把对象里的值完全复制给另一个对象,如A=B。这时,如果B中有一个成员变量指针已经申请了内存,那A中的那个成员变量也指向同一块内存。这就出现了问题:当B通过使用析构函数等方式把内存释放了,这时A内的指针就是野指针(悬挂指针),运行错误。