浅拷贝和深拷贝
如果属性有在堆区开辟内存的,一定要自己提供拷贝构造函数,进行深拷贝,以免堆区内存重复释放。
浅拷贝
- 浅拷贝会带来的问题是堆区空间重复释放
cpp
因为是浅拷贝,在调用第二个对象的析构函数时,会报错
code:
#include<iostream>
using namespace std;
#include"circle.h"
class Person
{
public:
int age;
int* p_height;
Person(int ref_age, int ref_height)
{
age = ref_age;
p_height = new int(ref_height);
cout << "堆区开辟的地址为: " << p_height << endl;
cout << "有参构造函数被调用," << "年龄是:" << age << ",身高是:" << *p_height << endl;
}
~Person()
{
cout << p_height << endl;
if(p_height != NULL)
{
delete p_height;
p_height = NULL;
}
cout << "析构函数被调用" << endl;
}
};
void test1()
{
Person p1(11, 160);
Person p2(p1);
}
void main()
{
test1();
system("pause");
}
result:
堆区开辟的地址为: 0000020FB4F36310
有参构造函数被调用,年龄是:11,身高是:160
0000020FB4F36310
析构函数被调用
0000020FB4F36310
报错
深拷贝
- 重新在堆区申请内存空间
cpp
code:
#include<iostream>
using namespace std;
#include"circle.h"
class Person
{
public:
int age;
int* p_height;
Person(int ref_age, int ref_height)
{
age = ref_age;
p_height = new int(ref_height);
cout << "堆区开辟的地址为: " << p_height << endl;
cout << "有参构造函数被调用," << "年龄是:" << age << ",身高是:" << *p_height << endl;
}
Person(const Person& ref_p)
{
age = ref_p.age;
p_height = new int(*ref_p.p_height); // 堆区重新申请空间
//p_height = ref_p.p_height; //编译器默认实现的是这行代码
cout << "拷贝构造函数被调用, " << "堆区开辟的地址为:" << p_height << endl;
}
~Person()
{
cout << p_height << endl;
if(p_height != NULL)
{
delete p_height;
p_height = NULL;
}
cout << "析构函数被调用" << endl;
}
};
void test1()
{
Person p1(11, 160);
Person p2(p1);
}
void main()
{
test1();
system("pause");
}
result:
堆区开辟的地址为: 0000021DED9361D0
有参构造函数被调用,年龄是:11,身高是:160
拷贝构造函数被调用, 堆区开辟的地址为:0000021DED936990
0000021DED936990
析构函数被调用
0000021DED9361D0
析构函数被调用