先那我寫的作爲一個例子來說明吧
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);//深拷貝
}
不使用引用,重寫拷貝構造,成功運行