編譯器必須為類合成預設建構函式的情況

2021-10-08 23:06:02 字數 1077 閱讀 5381

有4種情況,編譯器必須為未宣告建構函式的類合成預設建構函式,c++standard將其稱作有用的隱式預設建構函式。被合成出來的建構函式只能滿足編譯器的需要,而非程式。

在合成的預設建構函式中,只有基類子物件和成員物件會被初始化,所有其他的非靜態資料成員都不會被初始化。提供初始化操作的人應該是程式設計師。

若乙個類沒有任何建構函式,但他有乙個成員物件,該物件具有預設建構函式。則編譯器需要對這個類生成乙個預設建構函式。但這個生成行為只有在建構函式真正需要被呼叫時才會發生。

在多個不同編譯模組中,編譯器如何避免合成多個預設建構函式呢?辦法是將合成的預設建構函式、拷貝建構函式、析構函式、拷貝賦值運算子都以內聯形式完成,內聯函式有靜態鏈結,不會被檔案外部看到,若函式過於複雜不能內聯,則合成乙個顯式的非內聯靜態例項。

若乙個沒有建構函式的類繼承自乙個帶有預設建構函式的基類,則這個類的預設建構函式需要合成出來,它將呼叫上一層基類的預設建構函式,對於乙個派生類而言,這個合成的建構函式和乙個被顯式提供的預設建構函式沒有什麼差異。

若設計者提供多個建構函式,但都沒有預設建構函式,那麼編譯器會擴充套件現有的每乙個建構函式,將所有必要的**加進去,它不會額外合成乙個新的預設建構函式。同時,如果存在帶有預設建構函式的成員物件,他們的建構函式也會在所有基類的建構函式被呼叫之後被呼叫。

若類宣告或繼承了乙個虛函式,編譯器會合成乙個虛函式。下面兩個擴張行為會在編譯期間完成。

1.乙個虛函式表會產生,存放類的虛函式位址

2.在每個物件中,乙個額外的成員指標會合成出來,其指向虛函式表位址。

虛繼承必須使虛基類在每乙個派生類物件中的位置在執行期準備妥當。由於物件型別可以改變,編譯器無法固定其成員實際偏移位置,因此必須改變執行訪問操作的**,使其可以延遲至執行期才決定下來。不同編譯器對虛繼承的實現有較大差異,可以通過在派生類物件的每乙個虛基類中安插乙個指標來完成(cfront做法)。所有經過引用或指標來對虛基類進行訪問的操作都可以通過指標完成。

合成的預設建構函式之所以能完成任務,是藉著呼叫成員物件或基類的預設建構函式,或為每個物件初始化其虛函式機制或虛基類機制而完成的。至於不符合這幾種情況,而又未宣告建構函式的類,他們的預設建構函式是無用的,實際上也並不會合成出來。

摘自《深度探索c++物件模型》

編譯器合成複製建構函式

定義 只有單個形參,該形參是對本類型別物件的引用 常用const修飾 這樣的建構函式成為複製建構函式。使用方式 1 顯示使用 用乙個同型別的物件初始化該物件時 2 隱式使用 將該型別的物件傳遞給函式或從函式返回該型別物件時。三種型別的複製建構函式 bitwise copy constructor 逐...

C 編譯器何時為使用者提供預設建構函式

第一種是類成員中有成員是類物件,並且該成員的類含有預設建構函式,那麼c 編譯器會幫你給這個類也生成乙個預設建構函式,用來呼叫其成員物件的建構函式,完成該成員的初始化構造。需要強調的是,如果這個成員的類也沒有給出缺省建構函式,那麼c 編譯器也不會幫你生成該類的預設建構函式。第二種情況是這個類的基類有預...

C 編譯器何時為使用者提供預設建構函式

第一種是類成員中有成員是類物件,並且該成員的類含有預設建構函式,那麼c 編譯器會幫你給這個類也生成乙個預設建構函式,用來呼叫其成員物件的建構函式,完成該成員的初始化構造。需要強調的是,如果這個成員的類也沒有給出缺省建構函式,那麼c 編譯器也不會幫你生成該類的預設建構函式。第二種情況是這個類的基類有預...