類裏有其餘對象則該對象叫成員對象;有成員對象的類叫 封閉類;函數
class CTyre // 輪胎類 { public: // 有參數構造函數 // 初始化成員變量m_radius和m_width CTyre(int r, int w):m_radius(r),m_width(w) { } private: int m_radius; // 半徑 int m_width; // 寬度 }; class CEngine // 引擎類 { // 默認會有無參數構造函數 }; class CCar // 汽車類 -- 封閉類 { public: // 有參數構造函數 // 對成員變量m_price初始化,對成員對象tyre初始化 CCar(int p, int tr, int tw):m_price(p),tyre(tr,tw){} private: int m_price; // 價格 CTyre tyre; // 成員對象 CEngine engine; // 成員對象 }; int main() { CCar car(10000,20,50); return 0; }
上例中,若是CCar
類不定義構造函數,則會使用默認的無參構造函數,那麼下面的語句會編譯出錯:code
CCar car;
由於編譯器不明白CCar
類中的tyre
成員對象該如何初始化。engine
成員對象的初始化則沒問題呢,由於用默認構造函數便可。對象
任何生成封閉類對象的語句,都要讓編譯器明白,對象中的成員對象,是如何初始化的。編譯器
具體的作法是:經過封閉類的構造函數的初始化列表。編譯
class CTyre // 輪胎類 { public: CTyre(){ std::cout << "CTyre 構造函數" << std::endl; } ~CTyre(){ std::cout << "CTyre 析構函數" << std::endl; } }; class CEngine // 引擎類 { public: CEngine(){ std::cout << "CEngine 構造函數" << std::endl; } ~CEngine(){ std::cout << "CEngine 析構函數" << std::endl; } }; class CCar // 汽車類 -- 3. 最後構造封閉類對象 { public: CCar(){ std::cout << "CCar 構造函數" << std::endl; } ~CCar(){ std::cout << "CCar 析構函數" << std::endl; } private: CTyre tyre; // 1. 先構構造該成員對象 CEngine engine; // 2. 接着構造該成員對象 }; int main() { CCar car; return 0; }
執行結果:class
CTyre 構造函數 CEngine 構造函數 CCar 構造函數 CCar 析構函數 CEngine 析構函數 CTyre 析構函數
class A { public: // 無參數構造函數 A() { std::cout << "A 構造函數" << std::endl; } // 複製構造函數 A(A & a) { std::cout << "A 複製構造函數" << std::endl; } }; class B { // 若沒有聲明構造函數和複製構造函數,則編譯器會默認生成構造函數和複製構造函數 A a; // 成員對象 }; int main() { B b1; // b1對象 和 成員對象a都會執行無參數的構造函數 B b2(b1); // b2對象 和 成員對象a都會執行復制構造函數 return 0; }
輸出結果:變量
A 構造函數 A 複製構造函數