先那我写的作为一个例子来说明吧
person& operator=(person& p)//使用引用
{
if (m_age != NULL)
{
delete m_age;
m_age = NULL;
}
m_age = new int(*p.m_age);
return *this;
}
在VS下单步调试会发现,如果不使用引用执行到P2=P1这一步则会调用拷贝函数,不难理解,因为拷贝函数使用的三个场景就是:
1.使用已经创建的对象来初始化一个新建对象
person P1(10);
person P2(P1);//进入拷贝
2.值传递的方式给参数传值
void func(person p)//进入拷贝
3. 以值方式返回局部对象
person func()
{
person temp(10);
return temp;//进入拷贝
}
因为重载=,其实就是一个函数,如果不使用引用,就是第二种情况,而编译器默认的拷贝构造是浅拷贝的,即堆中数据一份,在函数退出时,系统自动回收形参,就会delete掉函数的参数也即例子中的p
而在这之后如果系统再使用这一个地址是肯定会出错的
解决方法:
1.使用引用,使用了引用就是别名,不会调用拷贝,自然也不会释放
2.那就是重写拷贝为深拷贝,如下:
person(const person& p)//拷贝构造
{
cout << "拷贝构造" << endl;
//m_age = p.m_age;//浅拷贝
m_age = new int(*p.m_age);//深拷贝
}
不使用引用,重写拷贝构造,成功运行