首先先进行浅拷贝,直接利用编译器给的默认拷贝构造进行拷贝
// 构造一个Person类 class Person { public: // 属性 int m_Age; // 年龄 int *m_Height; // 身高 用指针是为了开辟到堆区,方便验证 // 构造函数 Person() { cout << " 这是无参构造 " << endl; } // 有参构造 Person(int age,int height) { m_Age = age; m_Height = new int(height); // new int() 返回的就是一个指针 cout << " 这是有参构造 " << endl; } // 析构函数 ~Person() { // 析构代码,将堆区开辟的数据释放 if (m_Height != NULL) { delete m_Height; m_Height = NULL; } cout << " 这是析构函数 " << endl; } };
测试函数
void test() { Person p1(18,160); cout << "p1的年龄为:" << p1.m_Age << "p1的身高为:" << *p1.m_Height << endl; Person p2(p1); cout << "p2的年龄为:" << p2.m_Age << "p2的身高为:" << *p2.m_Height << endl; }
主函数
int main() { test(); system("pause"); return 0; }
这个时候如果直接运行,那么VS会崩盘
因为在测试的时候,堆区的先进后出,那么p2会先被释放,这时候就会用到析构函数,而析构函数里对身高进行了一个delete操作,又因为拷贝时,是直接用了同一个空间,那么身高在p2的时候就已经被释放了,p1的身高无法获取,就会变成误操作
浅拷贝带来的问题就是堆区的内存重复释放,所以要自己重写一下拷贝构造,让身高重新开辟一个空间,将拷贝过来的数值放到新开辟的空间,这样解决重复释放的问题
// 构造一个Person类 class Person { public: // 属性 int m_Age; // 年龄 int *m_Height; // 身高 用指针是为了开辟到堆区,方便验证 // 构造函数 Person() { cout << " 这是无参构造 " << endl; } // 有参构造 Person(int age,int height) { m_Age = age; m_Height = new int(height); // new int() 返回的就是一个指针 cout << " 这是有参构造 " << endl; } // 自己实现拷贝构造函数,来解决浅拷贝的问题 Person (const Person &p) { cout << "这是拷贝构造函数" << endl; m_Age = p.m_Age; // m_Height = p.m_Height; // 这是编译器默认实现的 // 深拷贝 m_Height = new int(*p.m_Height); } // 析构函数 ~Person() { // 析构代码,将堆区开辟的数据释放 if (m_Height != NULL) { delete m_Height; m_Height = NULL; } cout << " 这是析构函数 " << endl; } };