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

2022-02-19 02:48:32 字數 1517 閱讀 4566

建構函式、析構函式、賦值函式是每個類最基本的的函式。每個類只有乙個析構函式和乙個賦值函式。但是有很多建構函式(乙個為複製建構函式,其他為普通建構函式。對於乙個類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產生四個預設的函式,即 既然能自動生成函式,為什麼還需要自定義?原因之一是 預設的複製建構函...