自定析構意味着也要自定拷貝和賦值,自定拷貝意味着要自定賦值

一、需要析構意味着拷貝和賦值

如果自定義析構意味着有指針及其指向的動態內存,採用系統合成的拷貝和賦值將會默認共享動態內存,一旦一個對象離開其作用域,將會致使delete運算符多次釋放同一塊內存。

類使用指針管理內存,如下:

class HasPtr
{
public:
	HasPtr(const string &s=string()):ps(new string(s),i(0)){}//參數中分配動態內存
private:
    ~HasPtr(){delete ps;}//涉及到動態內存必須自定義析構delete這部分內存
	string * ps;
	int i;
};

ps實現了對new string的管理。如果用戶不自定義拷貝和賦值,編譯器將會默認拷貝指針本身,拷貝不會對動態內存進行拷貝。下面這個例子能夠告知爲什麼需要定義拷貝和賦值:

{
	HasPtr a;//構造
	HasPtr b=a;//拷貝構造,ok!b對象也有一個指針指向a對象動態內存
	HasPtr c;
	c=b;//拷貝賦值,ok! c對象也有一個指向a對象動態內存
}

當對象a離開其定義域,調用析構函數進行delete動態內存,成功刪除了!接着輪到對象b析構,再次調用析構函數delete已經析構的a中動態內存,這就有問題了,這部分內容已經不存在了,因此是一個嚴重的設計錯誤;同理c也將會析構一次,同樣是出錯。

二 、需要拷貝也需要賦值

拷貝定義了拷貝應該完成的操作,如序列號+1實現每一個對象都有一個獨一序列號,如果沒有封住賦值是不是實現不了了?沒錯,所以拷貝也要賦值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章