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

深度探索 C++ 物件模型 (4):建構函式語意與編譯器合成機制

     編輯:關於C++

建構函式語意學

本章探討建構函式如何運作,而非單純語法。編譯器在必要時合成 nontrivial default constructor,處理成員初始化、基類鏈、虛擬函式表指標設定。

四種觸發編譯器合成預設建構函式的情況

  1. 含有帶預設建構函式的成員物件:
    class Cat { public: Cat(); };
    class Dog { public: Dog(); };
    class Pet { Cat c; Dog d; Bird b; Fish f; int i; }; // 無使用者建構函式
    // 編譯器合成:
    inline Pet::Pet() { c.Cat::Cat(); d.Dog::Dog(); b.Bird::Bird(); f.Fish::Fish(); i = 0; }
    若使用者提供 Pet::Pet() { i = 0; },編譯器擴張插入成員/基類初始化。
  2. 繼承自帶預設建構函式的基類:依宣告順序調用基類預設建構函式。
  3. 類別宣告虛擬函式:合成建構函式初始化 vptr 指向正確 vtable。
  4. 繼承鏈含虛擬基類:合成建構函式正確初始化每個類別物件的 vptr。

合成建構函式的限制

僅初始化基類子物件與成員物件。其他非靜態資料成員 (如 int i) 不會被初始化,需程式設計師自行處理。編譯器不負責完成所有工作。

比喻

若你惹官司 (設計類別) 卻無錢聘大律師 (寫建構函式),法院指派律師 (預設建構函式)。雖能力較弱 (trivial),但在律師行督導 (編譯器合成機制) 下能盡力達到最好 (nontrivial)。

心得

理解編譯器何時、如何合成建構函式,能避免「以為已初始化實則未初始化」的錯誤,掌握 C++ 物件初始化的完整語意。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved