浅拷贝和深拷贝
一、浅拷贝(Shallow Copy)
浅拷贝是指创建一个新对象,然后将其成员变量(包括指针成员)的值简单地复制到新对象中。
如果成员变量是值类型(如int、float等),那么直接复制其值;
如果成员变量是指针类型,则只复制指针的地址值,而不复制指针所指向的内存区域。
浅拷贝导致的问题
由于浅拷贝只是复制了指针的地址,而没有为指针所指向的内存区域分配新的空间,因此原始对象和新对象中的指针成员将指向同一块内存区域。这会导致一系列问题,如内存泄漏(如果两个对象都尝试释放同一块内存)、数据不一致(如果一个对象修改了通过指针访问的数据,另一个对象也会看到这些修改)等。
#include<iostream>
using namespace std;
//深拷贝和浅拷贝
class Person
{
public:
int age;
int *m_Height;
//默认构造函数
Person()
{
cout << "Person()" << endl;
}
//有参构造函数
Person(int age,int height)
{
this->age = age;
m_Height = new int(height);
cout << "Person(int age, int height)" << endl;
}
//拷贝构造函数
Person(const Person& p)
{
this->age = p.age;
m_Height = p.m_Height;
cout << "Person(const Person& p)" << endl;
}
//析构函数
~Person()
{
//将堆区开辟的数据进行释放
if (m_Height != NULL)
{
delete m_Height;
m_Height = NULL;
}
cout << "~Person()" << endl;
}
};
void test01()
{
Person p1(12, 180);
cout << "p1.age = " << p1.age << endl;
Person p2(p1);
}
int main()
{
test01();
return 0;
}
结果如下,显示两个对象释放了同一块内存:
报错原因如下:
由于系统自带的拷贝构造函数是浅拷贝
,只复制了对象本身的属性和值,但对于对象属性中的引用类型(如指针、动态分配的内存、容器、另一个对象等),浅拷贝只是复制了引用的地址,而没有复制引用的内容。这意味着,原对象和新对象中的引用类型将指向同一块内存。
二、深拷贝(Deep Copy)
深拷贝是指创建一个新对象,并为其所有成员变量(包括指针成员)分配新的内存区域,然后复制原始对象中的值到新对象的内存区域中。对于指针成员,深拷贝会创建一个新的内存区域,并将原始指针所指向的数据复制到新的内存区域中,然后将新对象的指针成员指向这块新内存。
深拷贝的优点
深拷贝确保了原始对象和新对象之间的完全独立,任何对新对象成员变量的修改都不会影响到原始对象,反之亦然。此外,它还避免了内存泄漏和数据不一致的问题。
在堆区重新开辟空间,进行拷贝:
// 深拷贝构造函数
Person(const Person &p)
{
this->age = p.age;
//m_Height = p.m_Height; //编译器实现
// 为m_Height指向的数据分配新的内存,并复制数据
m_Height = new int(*p.m_Height);
}