#include <iostream>
#include <string>
using namespace std;
class Person20 //定义类
{
public:
Person20(int age) //定义构造函数
{
m_Age = new int(age);
}
~Person20() //利用析构函数中释放内存
{
if (m_Age != NULL)
{
delete m_Age;
m_Age = NULL;
}
}
//========================================================
//不修改void test20代码的情况下,让函数正常运行需要添加这一段
//重载赋值运算符--深拷贝
void operator=(Person20 &p1)
{
//首先应该了解到,编译器提供的是浅拷贝m_Age = p.m_Age
//应先判断是否有属性在堆区,如果有先释放干净,随后执行深拷贝
if (m_Age != NULL)
{
delete m_Age;
m_Age = NULL;
}//已经释放干净
m_Age = new int(*p1.m_Age);
//你内存空间所对应的的值,我再开辟一个堆区内存空间来存放
//深拷贝
}
//========================================================
int* m_Age;
};
void test20()
{
Person20 p1(18);
Person20 p2(20);
p2 = p1;//赋值操作 对象整份拷贝
cout << "p1的年龄为: " << *p1.m_Age << endl;//输出 堆区开辟数据地址所对应的数值
cout << "p2的年龄为: " << *p2.m_Age << endl;//输出 堆区开辟数据地址所对应的数值
int main(void)
{
test20();
system("pause");
return 0;
}
p1的生命周期结束前,析构函数自动调用,然后判断m_Age=0x1234是否为空,当然此时m_Age=0x1234并不为空,然后delete释放m_Age所指向的堆区的内存空间(即0x1234这块堆区);
p2的生命结束前,析构函数自动调用,然后判断m_Age=0x1234是否为空,当然此时m_Age=0x1234也并不为空,然后delete再次释放m_Age所指向的堆区的内存空间(即0x1234这块堆区);
两次释放都指向同一块内存空间,造成堆区的数据重复释放,然后程序奔溃啦~,不改变test20代码情况下,利用成员函数重载等号运算符,因为是浅拷贝这一个出现问题,所以修改成深拷贝就行了啦,各自指向不同的堆区内存空间,后续用delete释放就不会出现问题。
我是爱吃芒果的程序员,如果不对敬请指正~
今天的代码就到这里啦~因为我马上要去吃饭啦~所以就不能跟你哔哔啦~我要好好吃饭长胖胖啊~