首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ 對象模型:Default Constructor 建構操作詳解 (第二章)

     編輯:關於C++

何時合成 Default Constructor?

C++ Standard:只有當編譯器**需要**時,才為無用戶聲明構造函數的類合成默認構造函數。合成構造函數僅執行編譯器所需的初始化,**不**初始化內建類型成員(如指針、整數)。

四種觸發合成的情況

  1. 含有默認構造函數的成員對象:需調用成員的默認構造。合成構造函數按聲明順序調用各成員默認構造。
  2. 繼承自有默認構造函數的基類:需調用基類默認構造。按繼承順序調用(多重繼承按基類聲明順序)。
  3. 類聲明虛函數:需初始化 vptr 指向正確 vtable。合成構造函數設置 vptr。
  4. 繼承鏈含虛基類:需初始化虛基類指針/偏移,確保運行期訪問正確。

合成構造函數的行為

  • 只初始化上述四類「編譯器關心」的成員(基類子對象、類類型成員、vptr、虛基類指針)。
  • **不**初始化內建類型數據成員(int, pointer, array 等)。這些初始化是程序員責任。
  • 若用戶提供了**任意**構造函數,編譯器**不再**合成默認構造函數,而是擴張現有構造函數,在用戶代碼前插入必要的初始化調用。

初始化順序

  1. 基類構造函數(按繼承聲明順序)。
  2. 成員對象構造函數(按類中聲明順序)。
  3. 派生類自身構造函數體(用戶代碼)。

這保證了基類先於成員,成員先於派生類邏輯構造完成。

虛函數與 vptr 初始化

編譯器為每個含虛函數的類生成 vtable。構造函數中設置對象的 vptr 指向該類的 vtable。派生類構造時,先調用基類構造(設置基類 vptr),再設置派生類 vptr(覆蓋),最終對象 vptr 指向派生類 vtable。複製構造同理:必須顯式設置正確 vptr,不能位複製。

虛基類構造

虛基類在最派生類中只有一個實例。編譯器在構造函數中插入代碼,通過虛基類指針/偏移表定位並構造虛基類子對象。這在運行期完成,故破壞位逐次拷貝語意。

常見誤區

  1. 「任何無構造函數的類都會被合成默認構造函數」——**錯**,只有編譯器需要時才合成。
  2. 「合成默認構造函數會將所有成員初始化為 0/NULL」——**錯**,僅初始化編譯器需要的部分(基類、類成員、vptr、虛基類),內建類型**不**初始化。

總結

  • 默認構造函數合成條件:四種「編譯器需要」情況之一。
  • 合成內容:調用基類/成員默認構造、設置 vptr、修正虛基類指針。
  • 初始化順序:基類 → 成員 → 自身。
  • 用戶自定義構造函數會阻止默認構造函數合成,編譯器擴張用戶構造函數插入必要初始化。
  • 內建類型成員初始化完全由程序員負責。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved