複製建構函式與賦值函式

2021-09-07 16:55:42 字數 1933 閱讀 7268

建構函式、析構函式、賦值函式是每個類最基本的的函式。每個類只有乙個析構函式和乙個賦值函式。但是有很多建構函式(乙個為複製建構函式,其他為普通建構函式。對於乙個類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);

為類新增賦值運算子函式:

型別定義

classcmystring

;

要點:

1、返回值型別為該型別的引用,並在函式結束前返回例項自身的引用(即 *this);

2、是否把傳入的引數宣告為常量引用【const cmystring &str】;

3、是否釋放自身已有記憶體,否則會造成「記憶體洩漏」;

4、是否判斷引數與當前示例是指向的同乙個物件;

解法:

/*適用於初級c++程式設計師的解法

*/cmystring &cmystring::operator=(const cmystring &str) /*適用於高階c++程式設計師的解法 */cmystring &cmystring::operator=(const cmystring &str) //自動呼叫strtemp的析構函式,銷毀strtemp物件並**ptemp的記憶體 return *this; }

C 賦值建構函式 複製建構函式

編譯器提供乙個不接受任何引數,也不執行任何操作的建構函式,稱之為預設建構函式 這是因為創造物件的時候總會呼叫預設建構函式 klunk klunk 定義 klunk lunk 宣告 使用預設建構函式 如果定義了建構函式,c 不會定義預設建構函式,如果希望建立物件時不顯示地對他進行初始化,則必須顯示的定...

複製建構函式 與 賦值函式 的區別

建構函式 析構函式 賦值函式是每個類最基本的的函式。每個類只有乙個析構函式和乙個賦值函式。但是有很多建構函式 乙個為複製建構函式,其他為普通建構函式。對於乙個類a,如果不編寫上述四個函式,c 編譯器將自動為a產生四個預設的函式,即 既然能自動生成函式,為什麼還需要自定義?原因之一是 預設的複製建構函...

複製建構函式 與 賦值函式 的區別

建構函式 析構函式 賦值函式是每個類最基本的的函式。每個類只有乙個析構函式和乙個賦值函式。但是有很多建構函式 乙個為複製建構函式,其他為普通建構函式。對於乙個類a,如果不編寫上述四個函式,c 編譯器將自動為a產生四個預設的函式,即 既然能自動生成函式,為什麼還需要自定義?原因之一是 預設的複製建構函...