面試:C++的深複製和淺複製(轉)
阿新 • • 發佈:2019-01-30
物件的構造,也可以由複製建構函式完成,即用一個物件的內容去初始化另一個物件的內容。此時,若物件使用了堆空間(注意和“堆物件”區分),就有深、淺複製的問題,不清楚則很容易出錯。
什麼是淺複製
預設複製建構函式:用一個物件的內容初始化另一個同類物件,也稱為預設的按成員拷貝,不是對整個類物件的按位拷貝。這種複製稱為淺複製。
class CGoods
{
char *Name; //不同與char Name[21] ?
int Amount;
float Price;
float Total_value;
public:
CGoods()
{
Name=new char[21];
}
CGoods(CGoods & other)
{ //預設拷貝構造內容:
this->Name=other.Name;
this->Amount=other.Amount;
this->Price=other.Price;
this->Total_value=other.Total_value;
}
~CGoods()
{
delete Name;
}//解構函式
}; //類宣告結束
淺複製可能帶來什麼問題
void main()
{
CGoods pc; //呼叫預設建構函式
CGoods pc1(pc); //呼叫複製建構函式
} //程式執行完,物件pc1和pc先後析構,此時出錯。
出現錯誤的原因:析構時,如果用預設析構,則動態分配的堆空間不能回收。如果用有“delete Name;”語句的解構函式,則先析構pc1時,堆空間已經釋放,然後再析構pc時出現了二次釋放的問題。
解決方法:重新定義複製建構函式,給每個物件獨立分配一個堆字串,稱深複製。
深複製——自定義複製建構函式
CGoods(CGoods & other)
{ //自定義拷貝構造
this->Name=new char[21];
strcpy(this->Name,other.Name);
this->Amount=other.Amount;
this->Price=other.Price;
this->Total_value=other.Total_value;
}