拷貝控制之拷貝建構函式

2021-08-22 18:02:20 字數 1207 閱讀 6566

當我們定義乙個類的時候。我們通常會顯式或隱式的指定在此類的物件在建立、移動、銷毀的時候要做些什麼。

乙個類通常通過定義五種特殊的成員函式來控制這些操作:拷貝建構函式、拷貝賦值運算子、移動建構函式、移動賦值運算子、析構函式。

如果我們沒有定義這些成員函式,編譯器會自動定義些缺失的操作。有時也會造成些意想不到的錯誤。

如果乙個建構函式的第乙個引數是自身型別的引用,且任何額外引數都有預設值,則此建構函式是拷貝建構函式。

class foo;
拷貝建構函式第乙個引數必須是引用型別。(原因後面解釋)

拷貝構造函式引數幾乎總是乙個const的引用。

拷貝建構函式會經常被隱式的使用,所以通常不應該宣告成explicit。

如果未定義拷貝建構函式,編譯器會為我們定義乙個。

即使定義了其他建構函式,編譯器也會為我們合成乙個拷貝建構函式。

一般情況,編譯器從給定物件中一次將每個非static成員拷貝到正在建立的物件當中。

對類型別的成員,則呼叫他的合成拷貝函式。對於其他型別的成員,則直接拷貝。

我們可以從下面幾個例子裡看出初始化與拷貝初始化的不同。

string dots(10, '.');        //直接初始化

string s(dots); //直接初始化

string s2 = dots; //拷貝初始化

string null_book = "9-999-99999-9"; //拷貝初始化

string nines = string(100, '9'); //拷貝初始化

現在,只用了解拷貝初始化何時發生,以及拷貝初始是依靠拷貝建構函式或移動建構函式來完成的。

不僅在=定義變數時會發生,還會在下列情況發生:

·將乙個物件作為實參傳遞給非引用型別的形參。

·從乙個返回型別為非引用型別的函式返回乙個物件。

·用花括號列表初始化陣列元素或乙個聚合類的成員。

當初始化標準庫容器或呼叫其insert或push函式時,會使用拷貝初始化。

用emplace成員建立的元素都進行直接初始化。

在函式呼叫過程中,具有非引用型別的引數要進行拷貝初始化。當乙個函式具有非引用型別的返回型別時,返回值會被用來初始化呼叫方法的結果。

拷貝建構函式被用來初始化非引用型別的引數。所以拷貝建構函式的引數必須是引用型別。

拷貝建構函式,預設拷貝建構函式

拷貝建構函式,預設拷貝建構函式 1.c 的預設拷貝建構函式,從深度拷貝和淺拷貝說起 c 類的預設拷貝建構函式的弊端 c 類的中有兩個特殊的建構函式,1 無參建構函式,2 拷貝建構函式。它們的特殊之處在於 1 當類中沒有定義任何建構函式時,編譯器會預設提供乙個無參建構函式且其函式體為空 2 當類中沒有...

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

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

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

若採用系統預設的拷貝建構函式,為淺拷貝,對於指著型資料,會存在共同指向乙個位址空間,若p2析構時刪除了位址空間,那麼p1析構時,系統就會崩潰 所以要用new重新開闢乙個位址空間,成為深拷貝 include stdafx.h include using namespace std class pers...