一、default constructor
1. 對於class x ,如果沒有任何user-declared constructor,那麼編譯器生成的default constructor是無用的
2. 編譯器合成(擴張)的default constructor 是有用的4中情況
①.帶有default constructor的member class object
member class object 的default constructor會在合成(擴張)的default constructor呼叫。
②.帶有default constructor的base class
合成(擴張)的default constructor會呼叫base class的default constructor
③.帶有乙個virtual funtion的class
合成(擴張)的default constructor會初始化類的vptr
④.帶有乙個virtual base class的class
3. 誤區
①.任何class如果沒有定義default constructor,就會被合成出來。
②.編譯器合成出來的default constructor 會被明確設定class內的每乙個data member的預設值。
二、copy constructor
1. 有三種情況,會以乙個object的內容作為另乙個class的初值。
①.明確的以乙個object的內容作為另乙個class object的初值 x xx = x;
②.當object被當作引數交給某個函式時 void foo(x x)
③.當函式傳回乙個class object x = foo()
如果定義了copy constructor則大多數情況下會被呼叫,否則其內部是以所謂的default memberwise initialization 手法完成,對於其中member class object是以遞迴方式施行memberwise initialization。
2. 編譯器會合成copy constructor的情況即class不表現出bitwise copy semantics
①.當class內含乙個member object而後者的class宣告有乙個copy constructor時(具備條件合成的)
②.當class繼承自乙個base class而後者存在有乙個copy constructor(被明確宣告或被合成)
③.當class宣告了乙個或多個virtual funtions時
④.當class派生自乙個繼承串鏈,其中有乙個或多個virtual base classes時
下面對第三點做簡要說明:
我們知道編譯期間的兩個程式擴張操作(有virtual funtion存在的前提下)
i.增加乙個virtual function table(vtbl),內含每乙個有作用的virtual function的位址
ii.將乙個指向virtual function table的指標(vptr),安插在每乙個class object內
從這兩點我們可以看出編譯器需要合成出乙個copy constructor以求將vptr適當的初始化。
class zooanimal
public:
zooanimal(){}
virtual ~zooanimal(){}
virtual void animate(){}
virtual void draw() {}
class bear : public zooanimal
public:
bear(): b(5)
virtual void animate(){}
virtual void draw() {}
virtual void dance(){}//父類沒有的虛函式
bear yogi;
bear winnine = yogi;
這種情況下yogi的vptr值拷貝給winner的vptr是安全的,也就說此時兩個物件的vptr完全一樣。
但是下面這種情況
zoonanimal franny = yogi;
此時franny的vptr不可以被設定指向bear class的virtual table。也就說合成出來的zoonanimal copy constructor會明確設定object的vptr指向zoonanimal class的virtual table,而不是直接從右手邊的class object將其vptr現值拷貝過來
三、成員初值列(member initialization list)
1. 為了通過編譯必須使用member initialization list的情況
① 當初始化乙個reference member
② 當初始化乙個const member
③ 當呼叫乙個base class的constructor,而它擁有一組引數時
④ 當呼叫member class的constructor,而它擁有一組引數時
初始化順序不是有list中的專案順序而是有member宣告次序決定;編譯器會一一操作initialization list根據宣告次序在constructor內安插初始化操作,並且在任何explicit user code之前。
C 建構函式詳解
c 類的建構函式詳解 一 建構函式是幹什麼的 class counter private 資料成員 int m value 該類物件被建立時,編譯系統物件分配記憶體空間,並自動呼叫該建構函式 由建構函式完成成員的初始化工作 eg counter c1 編譯系統為物件c1的每個資料成員 m value...
c 建構函式詳解
c 類的建構函式詳解 一 建構函式是幹什麼的 class counter private 資料成員 int m value 該類物件被建立時,編譯系統物件分配記憶體空間,並自動呼叫該建構函式 由建構函式完成成員的初始化工作 eg counter c1 編譯系統為物件c1的每個資料成員 m value...
C 建構函式詳解
c 建構函式的知識在各種c 教材上已有介紹,不過初學者往往不太注意觀察和總結其中各種建構函式的特點和用法,故在此我根據自己的c 程式設計經驗總結了一下c 中各種建構函式的特點,並附上例子,希望對初學者有所幫助。c 類的建構函式詳解 一 建構函式是幹什麼的 class counter private ...