有三種情況,會以乙個object的內容作為另乙個class object的初值:
cpp**
class x ;
x x;
x xx = x; // 情況1,賦值物件
extern
void foo( x x);
void bar()
x foo_bar()
default memberwise initalization
如果class 沒有提供乙個explicit copy constructor又當如何?當class object 以 「相同class的另乙個object」作為初值時,其內是以所謂的default memberwise initalization手法完成的,也就是把每乙個內建的或派生的data member的值,從某個object拷貝乙份到另乙個object身上。不過它不會拷貝其中的member class object, 而是以遞迴的方式實行memberwise initalization.
例子:cpp**
class string
;
class word
;
指出乙個錯誤概念:「如果乙個class未定義copy constructor,編譯器就自動為它產生出乙個」這句話不對
正確的概念:default constructor 和 copy constructor在必要的時候才由編譯器產生出來。「必要」意指當class不展現bitwise copy semantics時。
bitwise copy semantics(位逐次拷貝)
上例展示了bitwise copy semantics.
有一點很值得注意:在被合成出來的copy constructor中,如整數、指標、陣列等等的nonclass memebers也都會被複製,正如我們所期待的一樣。
不要bitwise copy semantics
有四種情況不展示bitwise copy semantics, 不展示的時候需要編譯器合成copy constructor:
(1)當class內含乙個member object而後者的class宣告有乙個copy constructor時
(2)當class繼承自乙個base class 而後者存在有乙個copy constructor時
(3)當class宣告了乙個或多個virtual functions時
(4)當class派生自乙個繼承串鏈,其中有乙個或多個virtual base classes時
結論:如果是自定義複製建構函式時,需要自己把每乙個資料成員複製;如果是沒有自定義複製建構函式,無論是合成或非合成,編譯器都會自動複製每乙個資料成員。複製建構函式的用途是:如果建構函式中存在動態記憶體分配,則必須定義複製建構函式,否則會出現「指標懸掛問題」。
cpp**
class a
};
在這種情況下,複製物件,會造成兩個物件的成員指向同一位址。
重新設定virtual table的指標
例子:cpp**
class zooaninal
; class bear : public zooanimal()
;
bear yogi;
bear winnie = yogi;
把yogi 的vptr值拷貝給winnie的vptr是安全的
切割行為
不是直接從右手邊的class object中將其vptr現值拷貝過來。
處理virtual base class subobject
總結:可以這麼認為,並不是在沒有自定義copy constructor的時候編譯器就合成乙個copy constructor,而是在沒有bitwise copy semantics時會合成乙個 ,在執行default memberwise initialization的時候。
並沒有把這個操作當做在copy constructor的時候執行,這個操作並不認為是在copy constructor的時候完成的。這是我對這本書這一節的理解。
深度探索C 物件模型 Function語意學
nonstatic member function設計準則 與一般非成員函式 nonmember function 有相同的執行效率。因此,實際上編譯器內部將nonstatic member 函式實體轉化為對等的nonmember 函式實體。轉換過程 1.新增額外this指標,提供資料訪問管道 2....
深度探索C 物件模型 Data語意學筆記
class x class y public virtual x class z public virtual x class a public y,public z 它們的sizeof結果如下 sizeof x 1 sizeof y 8 視編譯器不同而不同 sizeof z 8 視編譯器不同而不同...
深度探索C 物件模型學習筆記 Data語意學
例子 class x class y public virtual x class z public virtual x class a public y,public z 物件大小由下述原因決定 1.語言本身所造成的額外負擔 如 支援virtual base classes時,derived cl...