本章探討建構函式如何運作,而非單純語法。編譯器在必要時合成 nontrivial default constructor,處理成員初始化、基類鏈、虛擬函式表指標設定。
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; },編譯器擴張插入成員/基類初始化。vptr 指向正確 vtable。vptr。僅初始化基類子物件與成員物件。其他非靜態資料成員 (如 int i) 不會被初始化,需程式設計師自行處理。編譯器不負責完成所有工作。
若你惹官司 (設計類別) 卻無錢聘大律師 (寫建構函式),法院指派律師 (預設建構函式)。雖能力較弱 (trivial),但在律師行督導 (編譯器合成機制) 下能盡力達到最好 (nontrivial)。
理解編譯器何時、如何合成建構函式,能避免「以為已初始化實則未初始化」的錯誤,掌握 C++ 物件初始化的完整語意。