date: 2019-12-24 14:07:01
浅拷贝
简单的赋值拷贝操作(编译器默认)
class Person
{
public:
//无参(默认)构造函数
Person()
{
}
//有参构造函数
Person(int age, int height)
{
m_Age = age;
m_Height = new int(height);
}
//拷贝构造函数
Person(const Person& p)
{
m_Age = p.m_Age;
m_Height = p.m_Height;//编译器默认操作
}
//析构函数
~Person()
{
if (m_Height != NULL) //手动释放堆区
{
delete m_Height;
m_Height = NULL;
}
}
int m_Age;
int* m_Height;
};
此时编译将会出现异常,原因是拷贝构造函数赋值编译器默认操作为
m_Height = p.m_Height;
两个对象指向同一个堆区地址,析构函数对堆区数据进行释放时会产生对堆区数据重复释放的问题;解决方法是深拷贝。
深拷贝
在堆区重新申请空间,在进行拷贝操作
class Person
{
public:
//无参(默认)构造函数
Person()
{
}
//有参构造函数
Person(int age, int height)
{
m_Age = age;
m_Height = new int(height);
}
//拷贝构造函数
Person(const Person& p)
{
m_Age = p.m_Age;
m_Height = new int(*p.m_Height);
}
//析构函数
~Person()
{
if (m_Height != NULL) //手动释放堆区
{
delete m_Height;
m_Height = NULL;
}
}
int m_Age;
int* m_Height;
};
void test01()
{
Person p1(18, 160);
Person p2(p1);
}
重写拷贝构造函数,在堆区重新申请空间,解决浅拷贝导致的堆区重复释放的问题。
m_Height = new int(*p.m_Height);
总结
如果属性有在堆区开辟,需要自己提供拷贝构造函数,防止浅拷贝带来的堆区重复释放的问题。