C 之拷貝建構函式

2021-10-04 14:48:10 字數 2030 閱讀 8026

拷貝建構函式最常見的是當我們建立的物件是用該類的另乙個物件來進行初始化的,此時呼叫的建構函式就是拷貝建構函式。拷貝建構函式實質上就是建構函式的過載。當你不顯式定義拷貝建構函式的時候,c++會給你提供乙個預設拷貝建構函式,這和它提供預設建構函式是一樣的。但是當你一旦顯式定義了建構函式和拷貝建構函式,那麼c++將不再提供預設建構函式和預設拷貝建構函式。

下面這三種情形是常見的需要拷貝建構函式的場景。

乙個物件作為函式引數,進行值傳遞時,需要呼叫拷貝建構函式;

乙個物件作為函式返回值,進行值傳遞,需要呼叫拷貝建構函式;

乙個物件用於給另乙個物件初始化時,需要呼叫拷貝建構函式。

拷貝建構函式原型:類名(類名&物件名);通常我們我們會使用const關鍵字來成為乙個常量引用。

下面給出一段**來演示一下上面這三種情形。

#include#includeusing namespace std;

class myclass

private:

int a;

};myclass::myclass() :a(3) //無參建構函式

myclass::myclass(const myclass &a) //拷貝建構函式

myclass myclass::show(myclass a) //這個函式的引數是物件做值傳遞,並且該函式的返回值也是物件做值傳遞。

int main()

我們的關注點主要在與main函式中,看一看這些建立物件,呼叫函式都會發生什麼?

myclass c;這句話無疑會呼叫myclass類的無參建構函式。然後接下來執行myclass c1(c),這句符合上述的條件3.即:乙個物件用於給另乙個物件初始化時,需要呼叫拷貝建構函式。這時候呼叫的就是拷貝建構函式。下面是c.show(c1);這句話的執行我們必須好好的進行分析。首先,c1作為引數進行值傳遞,需要呼叫一次拷貝建構函式;其次myclass::show()函式返回值也是進行值傳遞,又需要呼叫一次拷貝建構函式。然後引數a的生命週期結束,呼叫析構函式釋放物件;而該函式返回乙個匿名物件,該物件沒有被使用,因此生命週期也結束,然後呼叫析構函式。

接下來執行myclass c2 = c1.show(c);這句話。注意:如果按照c.show(c1)來接著分析,我們理所當然的會得出結論是這行**將會呼叫3次拷貝建構函式,呼叫兩次析構函式。

實際上並非如此,c++的編譯器設計者做了一定的優化措施。將匿名物件的記憶體空間直接給了c2物件。c2代替了匿名物件。因此只會呼叫兩次拷貝建構函式,一次析構函式。

剩餘的析構函式呼叫則是在程式結束之前呼叫。

預設拷貝建構函式就是執行淺拷貝操作。淺拷貝它只完成了值拷貝。

預設拷貝建構函式以記憶體拷貝的方式將舊有物件的記憶體空間的內容拷貝到新物件的記憶體空間。

下面來一段**。

//類cman

class cman

;

//cman類的建構函式和析構函式的實現

cman::cman(int age, char* p_name)

cman::cman()

cman::~cman()

int main()

我們來分析cman man3(man2);這行**執行以後,預設拷貝建構函式做了什麼?

預設拷貝建構函式在這個類中其實被實現為下面這樣。

cman::cman(const cman& man)

這就是程式在cman man3(man2);這行**處出現的錯誤。

這時候就需要我們自己動手實現乙個拷貝建構函式。在建構函式中沒有出現分配記憶體或者陣列的情形下,我們使用預設拷貝建構函式就足夠了。

深拷貝是需要在拷貝建構函式中進行記憶體分配或者是陣列賦值操作。上面這個類的拷貝建構函式可以寫成這樣。

cman::cman(const cman& man)

這樣就不會造成錯誤了。

C 拷貝建構函式之深拷貝 淺拷貝

對於普通型別的物件來說,它們之間的複製是很簡單的,例如 int a 88 int b a 而類物件與普通物件不同,類物件內部結構一般較為複雜,存在各種成員變數。下面看乙個類物件拷貝的簡單例子。執行程式,螢幕輸出100。從以上 的執行結果可以看出,系統為物件b分配了記憶體並完成了與物件a的複製過程。就...

C 之 拷貝建構函式 即複製建構函式

主要探索淺拷貝和深拷貝 拷貝建構函式是一種特殊的建構函式,函式的名稱必須和類名稱一致,它的唯一的乙個引數是本型別的乙個引用變數。當出現類的等號賦值時,會呼叫拷貝函式 在未定義顯示拷貝建構函式的情況下,系統會呼叫預設的拷貝函式 即淺拷貝,它能夠完成成員的一一複製。當資料成員中沒有指標時,淺拷貝是可行的...

C 建構函式 拷貝建構函式

建構函式 class base private int m var 建構函式無返回值型別,函式名和型別相同。拷貝建構函式傳遞引數為引用。1 class base2 7 拷貝建構函式 8 base base ref m var ref m var 9 11 private 12 intm var 13...