定義:
只有單個形參,該形參是對本類型別物件的引用(常用const修飾),這樣的建構函式成為複製建構函式。
使用方式:
(1)顯示使用----用乙個同型別的物件初始化該物件時;
(2)隱式使用----將該型別的物件傳遞給函式或從函式返回該型別物件時。
三種型別的複製建構函式:
*bitwise copy constructor :逐位複製-----預設方式
*合成的 copy constructor :編譯器合成----執行逐個成員初始化(memberwise initialize),只完成必要的工作,
*自定義的copy constructor:由類設計者定義------因為有些類必須對複製物件加以控制,如資料成員是指標的情況或者資料成員表示在建構函式中分配的其他資源,或類在建立新物件時必須要做一些特定工作,這時候就需要定義自己的複製建構函式。
關於淺拷貝與深拷貝:
淺拷貝:shllow copy= bitwise copy-----逐位(位元組)拷貝(預設情況)
例子:[cpp]view plain
copy
print?
"font-size:24px;">class base
base b1;
b1.a=15;
b1.ch='c';
b1.str="string";
b2=b2;
現在看看b1和b2的記憶體布局(不考慮對齊):
可以看到:b1.str和b2.str指向了同一記憶體空間,即當一方撤銷時,另一方將受到影響,故應極力避免這種情況-----深度拷貝
深度拷貝:deep copy = memberwise copy-----挨個成員拷貝
再看b1和b2的記憶體布局:
此時b1.str和b2.str指向了不同的記憶體空間,但內容
(string)
還是一樣的。
由於編譯器預設是bitwise copy semantics
即如果類中沒有明確定義或被編譯器合成copy constructor(即memberwise copy
),則預設使用bitwise copy形式。
注:以上編譯器合成copy constructor和bitwise copy constructor兩種情況,均不需要類設計的參與!
那麼什麼 情況下bitwise copy semantics會失效呢?
有四種情況:
(1)當class內含乙個class member object ,而後者的class宣告有乙個copy constructor 時----被class設計者明確宣告或被編譯器合成-------遞迴呼叫;
(2)當class繼承自乙個base class,而後者存在乙個copy constructor時-----被class設計者明確宣告或被編譯器合成-------遞迴呼叫;
(3)當class宣告了乙個或多個virtual functions時-------因為此時要考慮類物件中的虛函式表指標vptr的值。
當在同層物件之間進行初始化時,bitwise copy已經夠用了(為簡化,此時不考慮含有指標成員的情況);
例子:[cpp]view plain
copy
print?
"font-size:18px;">class zooanimal;
class bear : public zooanimal;
bear yogi;
bear winnie = yogi; //bitwise copy
其記憶體布局如下:
但是如果存在:當乙個base class object以其derived class 的object內容做初始化操作時,此時若bitwise copy顯然會出錯,因為其vptr將指向不同的虛表,故此時編譯器需要合成copy constrctor,以保證vptr複製操作的安全。合成出來的base class object copy constructor會明確是定object的vptr指向base class object 的vitrual table,而不是直接從右手邊的class object 中將其vptr現值拷貝過來。 如:
[cpp]view plain
copy
print?
"font-size:18px;">void draw(const zooanimal& zoey )
zooanimal franny = yogi;//發生切割(sliced)行為
draw(yogi); //呼叫bear::draw();
draw(franny); //呼叫zooanimal::draw()
其記憶體布局如下(此時由編譯器合成copy constructor):
(4)當class派生自乙個繼承串鏈時,其中有乙個或多個virtual base classes時。
C 編譯器合成預設建構函式和複製控制成員的條件
參考自 深入理解c 物件模型 c 新手一般有兩個常見的誤解 任何class如果沒有定義default constructor,就會被合成乙個出來.編譯器合成出來的default constructor會明確設定class 內每乙個data member的預設值.現在主要解釋第一條為什麼是錯誤的,根據...
編譯器角度看C 複製建構函式
關於複製建構函式的簡單介紹,可以看我以前寫過的一篇文章 複製控制之複製建構函式該文章中介紹了複製建構函式的定義 呼叫時機 也對編譯器合成的複製建構函式行為做了簡單說明。本文因需要會涉及到上文的一些知識點,但還是推薦先閱讀上文。本文主要從編譯器角度對複製建構函式進行分析,糾正以前對複製建構函式的一些錯...
編譯器合成copy constructors
編譯器合成copy constructors 當class 不展現bitwise copy semantics時編譯器會產生出來乙個copy constructors且缺乏乙個已宣告的copy constructor時 和default constructors一樣copy constructors...