explicit被引入c++是為了使程式設計師能夠制止「單一引數的constructor函式」被當做乙個conversion 運算子。
有四種情況:
1.帶有default constructor 的member classobject
2.帶有default constructor 的base class
3.帶有乙個virtual function 的class
4.帶有乙個virtual base class 的class
會導致「
編譯器必須為未宣告constructor 之classes 合成乙個default constructor(或copy constructor)
」。c++ stardand 把那些合成物稱為implicit nontrivial default constructors(或copy constructor)。被合成出來的constructor 只能滿足編譯器(而非程式)的需要。它之所以能夠完成任務,是藉著
「呼叫member object 或 base class 的default constructor(或copy constructor)」或是
「為每乙個object初始化其virtual function 機制或virtual base class 機制
」而完成。至於沒有存在那四種情況而又沒有宣告任何constructor的classes,我們說它們擁有的是implicit trivial default constructors(或copy constructor),它們實際上並不會被合成出來。
在合成的default constructor(或copy constructor)中,只有 base class subobjects 和member class objects 會被初始化。所有其它的nonstatic data member,如整數,整數指標,整數陣列等等都不會被初始化。這些初始化操作對程式而言或許有需要,但對編譯器則非必要。如果程式需要乙個
「把某指標設為0
」的default constructor,那麼提供它的人應該是程式設計師。
c++新手一般有兩個常見的誤解:
1.任何class如果沒有定義default constructor,就會被合成出乙個來。
2.編譯器合成出來的
default constructor
會明確設定
「class
內每乙個
data member
的預設值」。
但如你所見,沒有乙個是真的!
對於copy constructor,後兩種情況有些不同:
它們發生在當乙個
base class object以其derived class的object內容
做初始化操作時,
其vptr和virtual base class pointer/offset複製操作也必須保證安
全
,所以會合成出乙個
copy constructor 來做這件事。
member initialization list被使用於下面四種情況:
1.當初始化乙個reference member 時
2.當初始化乙個const member 時
3.當呼叫乙個base class 的constructor,而它擁有一組引數時
4.當呼叫乙個
member class 的constructor,而它擁有一組引數時
執行順序是先呼叫基類的建構函式,然後按照成員的宣告順序執行在
member initialization list中
進行初始化,最後執行建構函式主體
部分。
《深度探索C 物件模型》第二章 建構函式語意學
default constructor的構建操作 default constructors在需要的時候被編譯器產生。例 clas foo void foo bar 上述的 情況中,並不會生成乙個deafult constructor。需要注意的地方是 全域性的object內存在被啟用時會清0,而區域...
深度探索C 物件模型 第二章建構函式語意學
在使用c 時,常常會好奇或者抱怨,編譯器為我們做了什麼事呢?為什麼建構函式沒有為我初始化呢?為什麼我還要寫預設建構函式呢?2.1 default constructor 的構造操作 如果沒有宣告預設建構函式,編譯器會在需要的時候幫我們產生出來。為了避免在多個地方被需要導致重複,則編譯器將產生的建構函...
C 物件模型 拷貝建構函式語義
目錄引例 如果乙個類a沒有拷貝建構函式,但是含有乙個類型別ctb的成員變數m ctb。該型別ctb含有拷貝建構函式,那麼當 中有涉及到類a的拷貝構造時,編譯器就會為類a合成乙個拷貝建構函式。如果乙個類ctbson沒有拷貝建構函式,但是它有乙個父類ctb,父類有拷貝建構函式,當 中有涉及到類ctbso...