建構函式、析構函式、賦值函式是每個類最基本的的函式。每個類只有乙個析構函式和乙個賦值函式。但是有很多建構函式(乙個為複製建構函式,其他為普通建構函式。對於乙個類a,如果不編寫上述四個函式,c++編譯器將自動為a產生四個預設的函式,即:
既然能自動生成函式,為什麼還需要自定義?原因之一是「預設的複製建構函式」和"預設的賦值函式「均採用」位拷貝「而非」值拷貝「
位拷貝 v.s. 值拷貝
為便於說明,以自定義string類為例,先定義類,而不去實現。
#include using位拷貝拷貝的是位址,而值拷貝拷貝的是內容。namespace
std;
class
string
;
如果定義兩個string物件a, b。當利用位拷貝時,a=b,其中的a.val=b.val;但是a.m_data=b.m_data就錯了:a.m_data和b.m_data指向同乙個區域。這樣出現問題:
因此
當類中還有指標變數時,複製建構函式和賦值函式就隱含了錯誤。此時需要自己定義。
結論
注意
因此此時如果寫string s是錯誤的,因為定義了其他建構函式,就不會自動生成無參預設建構函式。
複製建構函式 v.s. 賦值函式
#include #include執行結果using
namespace
std;
class
string
;string::string(
const
char *str)
else
}string::string(
const string &other)
string & string::operator=(const string &other)
else
}string::~string(void
)int
main()
說明幾點
1. 賦值函式中,上來比較 this == &other 是很必要的,因為防止自複製,這是很危險的,因為下面有delete m_data,如果提前把m_data給釋放了,指標已成野指標,再賦值就錯了
2. 賦值函式中,接著要釋放掉m_data,否則就沒機會了(下邊又有新指向了)
3. 拷貝建構函式是物件被建立時呼叫,賦值函式只能被已經存在了的物件呼叫
注意:string a("hello"); string b("world"); 呼叫自定義建構函式
string c=a;呼叫拷貝建構函式,因為c一開始不存在,最好寫成string c(a);
複製建構函式 與 賦值函式 的區別
建構函式 析構函式 賦值函式是每個類最基本的的函式。每個類只有乙個析構函式和乙個賦值函式。但是有很多建構函式 乙個為複製建構函式,其他為普通建構函式。對於乙個類a,如果不編寫上述四個函式,c 編譯器將自動為a產生四個預設的函式,即 既然能自動生成函式,為什麼還需要自定義?原因之一是 預設的複製建構函...
複製建構函式 與 賦值函式 的區別
建構函式 析構函式 賦值函式是每個類最基本的的函式。每個類只有乙個析構函式和乙個賦值函式。但是有很多建構函式 乙個為複製建構函式,其他為普通建構函式。對於乙個類a,如果不編寫上述四個函式,c 編譯器將自動為a產生四個預設的函式,即 既然能自動生成函式,為什麼還需要自定義?原因之一是 預設的複製建構函...
複製建構函式與賦值函式
建構函式 析構函式 賦值函式是每個類最基本的的函式。每個類只有乙個析構函式和乙個賦值函式。但是有很多建構函式 乙個為複製建構函式,其他為普通建構函式。對於乙個類a,如果不編寫上述四個函式,c 編譯器將自動為a產生四個預設的函式,即 既然能自動生成函式,為什麼還需要自定義?原因之一是 預設的複製建構函...