c 複製 拷貝建構函式

2021-06-23 00:35:08 字數 1620 閱讀 4884

在c++中,定義乙個空類時,編譯器會預設宣告6個成員函式,它們分別是

class empty ;
注意 一下,編譯器預設合成的析構函式不是虛函式。 

首先,說一下什麼是拷貝建構函式(也可以叫複製建構函式),它是乙個特殊的建構函式,具有單個形參(此形參是對該類型別的引用,需要用const修飾,否則會無限迴圈呼叫複製建構函式)。一般這幾種情況會呼叫它:1.根據另乙個同型別的物件初始化乙個物件 2.複製乙個物件,將它作為實參傳遞給乙個函式 3.從函式返回時複製乙個物件。

只要我們不顯示的定義拷貝建構函式,編譯器都會自動合成乙個,這時候編譯器只是簡單對物件中的資料成員進行賦值,也就是淺拷貝。大致的內部實現如**所示

#include class test 

//自定義拷貝建構函式

test(test& c)

int m1;

};int main()

當然大多數情況下,淺拷貝是可以的,但是當類成員含有指標或者其它占有系統資源的變數時,由於淺拷貝只是簡單的賦值,會將新物件的指標也指向以前物件已經分配的堆記憶體空間,如果這時候以前的物件已經析構,新物件的指標就成為野指標,出現執行錯誤。

先看下含有指標成員的的類物件淺拷貝**

#include class test 

~test()

} int *p;

};int main()

輸出結果:

從輸出結果可以看出物件a和b中的指標成員p指向的是同一塊堆記憶體位址,若a物件先把記憶體釋放後在引用b中的p就會出現野指標的執行時錯誤。為了防止這種情況發生,我們需要自定義拷貝建構函式,對指標成員不是簡單的賦值,需要重新開闢一塊記憶體,將老物件指標指向的資料拷貝進去。這就是深拷貝。

看看深拷貝的實現:

#include class test 

//自定義拷貝建構函式(深拷貝)

test(test& c) }

//賦值運算子

test& operator=(const test &rhs)

~test()

} int *p;

};int main()

輸出結果:

可以看出物件a和b中的指標儲存的不是同一塊堆記憶體位址,它們中的資料是一樣的,這樣就可以防止出現野指標的執行時錯誤。由於只是做個簡單的測試,**有點偏向偽碼,類屬性其實需要定義為private,為了測試方便,直接使用public了。

需要注意下,一般情況類需要過載賦值運算子,因為我們不一定是直接初始化物件test b(a),我們可能會這樣寫test b = a這種賦值初始化。所以好的建議是自定義了拷貝建構函式後順便過載賦值運算子。

也就是說當類中含有指標這種需要占有系統資源的變數時,我們必須自定義拷貝建構函式(深拷貝)。淺拷貝說白了,就是簡單賦值,有指標成員時,拷貝的是指標,而深拷貝就是拷貝指標指向的物件。

c 拷貝(複製)建構函式

class line line line const line obj 拷貝建構函式是一種特殊的建構函式,它在建立物件時,是使用同一類中之前建立的物件來初始化新建立的物件。拷貝建構函式通常用於 1 通過使用另乙個同型別的物件來初始化新建立的物件,即用已有物件給新建立物件賦值。line line1 1...

拷貝建構函式(複製建構函式)

執行 物件a 物件b時,系統需要呼叫拷貝建構函式,如果程式設計師沒寫,則呼叫預設的拷貝建構函式。預設的拷貝建構函式利用淺拷貝方式,它的樣子是 a const a a 淺拷貝 拷貝的時候,兩個指標指向同乙個區域 char str1 helloworld char str2 str1 深拷貝 拷貝的時候...

C 拷貝構造 拷貝複製 析構函式

帶有指標的成員的類必須有拷貝建構函式和拷貝賦值函式,淺拷貝預設的賦值函式會將乙個指標賦值給另乙個,導致進行賦值的物件指標指向的內容記憶體洩漏 string.h ifndef mystring define mystring class string private char m data endif...