浅拷贝与深拷贝
我们通过代码来解释什么是浅拷贝,什么是深拷贝。
- 首先,写一个类Person,设置无参构造函数,有参构造函数,析构函数,姓名char*mName,年龄int mage ,编译器自动提供拷贝构造函数。
- 有参构造函数中传入参数(const char* name,int age),有参构造函数在设置const char* 时需要开辟堆空间来存储。因此,析构函数中需要将开辟的堆空间给free掉。
- 当主调函数中设置了拷贝构造函数时,生成的p2与p1是相同的,两个类对象中所存储的内容是一样的,第一个属性是char *,指针类型,指向某个地址,第二个属性是int,存储的是个数。两个类对象都指向相同的地址。
- 当析构函数free掉p1所指向的地址开辟的堆空间后,p2就找不到对应的地址了,p2的析构函数就会因此崩掉。这就是浅拷贝,仅仅是简单地复制。
- 要解决这个问题,就是深拷贝的方法。自己提供拷贝构造函数,设置拷贝构造函数不仅仅是简单地拷贝值,而是为新的拷贝开辟新的堆空间,这样两个类对象在析构函数free时就不会有错误了。
代码如下:
#define _CRT_SECURE_NO_WARNINGS#include using namespace std;class Person{public: //构造函数 Person() {} //有参构造函数 Person(const char* name, int age) { //姓名需要开辟堆空间 m_Name = (char*)malloc(strlen(name)+1); strcpy(m_Name, name); m_age = age; } //拷贝构造函数 系统提供默认拷贝构造,值拷贝 //深拷贝,自己提供拷贝构造函数。因为浅拷贝导致析构函数两次free Person(const Person& p) { m_age = p.m_age; //开辟新的堆空间, m_Name = (char*)malloc(strlen(p.m_Name) + 1); strcpy(m_Name, p.m_Name); } //析构函数 ~Person() { cout << "析构函数调用" << endl; //有参构造函数开辟了堆空间,需要free if (m_Name != NULL) { free(m_Name); m_Name = NULL; } } //姓名 char* m_Name; //年龄 int m_age;};void test01(){ Person p1("lol", 10); Person p2(p1); //调用了拷贝构造}int main(){ test01(); return 0;}
关注公众号【计算机视觉与深度学习】,获取海量计算机视觉与深度学习资源,实战项目源码,最新论文下载,大厂面试经验!!!