C++筆記之為什麼一個類定義了解構函式就幾乎肯定要定義拷貝建構函式和拷貝賦值運算子
阿新 • • 發佈:2019-02-19
這個問題本來很簡單,但是時間久了就容易忘,所以做個筆記用來提示下自己
先來看看這樣一個類:
class HasPtr
{
public:
HasPtr(const string& s = string()) :ps(new string(s)), i(0) {}
~HasPtr() { delete ps; }
private:
string * ps;
int i;
};
在HasPtr類裡面定義了解構函式,但是沒有定義拷貝建構函式和拷貝賦值運算子,這時,編譯器將自動為我們生成拷貝建構函式和拷貝賦值運算子,由於編譯器自動生成的僅僅是執行簡單的拷貝操作,所以對於指標,合成的版本也是僅僅拷貝其地址。
如果類外面有這樣一個函式:
HasPtr f(HasPtr hp)
{
HasPtr ret = hp;
///... 其他操作
return ret;
}
當函式執行完了之後,將會呼叫hp和ret的解構函式,將hp和ret的成員ps給delete掉,但是由於ret和hp指向了同一個物件,因此該物件的ps成員被delete了兩次,這樣產生一個未定義的錯誤,所以說:
如果一個類定義了解構函式,那麼它幾乎肯定要定義自己的拷貝建構函式和拷貝賦值運算子。