01 成員對象與封閉類
類里有其他對象則該對象叫成員對象;有成員對象的類叫 封閉類;
class CTyre // 輪胎類
{
public:
// 有參數(shù)構(gòu)造函數(shù)
// 初始化成員變量m_radius和m_width
CTyre(int r, int w):m_radius(r),m_width(w) { }
private:
int m_radius; // 半徑
int m_width; // 寬度
};
class CEngine // 引擎類
{
// 默認(rèn)會有無參數(shù)構(gòu)造函數(shù)
};
class CCar // 汽車類 -- 封閉類
{
public:
// 有參數(shù)構(gòu)造函數(shù)
// 對成員變量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類不定義構(gòu)造函數(shù),則會使用默認(rèn)的無參構(gòu)造函數(shù),那么下面的語句會編譯出錯:
CCar car;
因?yàn)榫幾g器不明白CCar類中的tyre成員對象該如何初始化。engine成員對象的初始化則沒問題呢,因?yàn)橛媚J(rèn)構(gòu)造函數(shù)即可。
任何生成封閉類對象的語句,都要讓編譯器明白,對象中的成員對象,是如何初始化的。
具體的做法是:通過封閉類的構(gòu)造函數(shù)的初始化列表。
02 封閉類構(gòu)造函數(shù)和析構(gòu)函數(shù)的執(zhí)行順序
- 封閉類對象生成時,先執(zhí)行所有成員對象的構(gòu)造函數(shù),然后才執(zhí)行封閉類的構(gòu)造函數(shù)。
- 成員對象的構(gòu)造函數(shù)執(zhí)行順序,與在封閉類定義成員對象的順序一致。
- 當(dāng)封閉類的對象消忙時,只需要記住一句話:先構(gòu)造的對象,后析構(gòu),由于封閉類是最后才被構(gòu)造的,所以封閉類對象最先析構(gòu)。
class CTyre // 輪胎類
{
public:
CTyre(){ std::cout << "CTyre 構(gòu)造函數(shù)" << std::endl; }
~CTyre(){ std::cout << "CTyre 析構(gòu)函數(shù)" << std::endl; }
};
class CEngine // 引擎類
{
public:
CEngine(){ std::cout << "CEngine 構(gòu)造函數(shù)" << std::endl; }
~CEngine(){ std::cout << "CEngine 析構(gòu)函數(shù)" << std::endl; }
};
class CCar // 汽車類 -- 3. 最后構(gòu)造封閉類對象
{
public:
CCar(){ std::cout << "CCar 構(gòu)造函數(shù)" << std::endl; }
~CCar(){ std::cout << "CCar 析構(gòu)函數(shù)" << std::endl; }
private:
CTyre tyre; // 1. 先構(gòu)構(gòu)造該成員對象
CEngine engine; // 2. 接著構(gòu)造該成員對象
};
int main()
{
CCar car;
return 0;
}
執(zhí)行結(jié)果:
CTyre 構(gòu)造函數(shù)
CEngine 構(gòu)造函數(shù)
CCar 構(gòu)造函數(shù)
CCar 析構(gòu)函數(shù)
CEngine 析構(gòu)函數(shù)
CTyre 析構(gòu)函數(shù)
03 封閉類的復(fù)制構(gòu)造函數(shù)
class A
{
public:
// 無參數(shù)構(gòu)造函數(shù)
A() { std::cout << "A 構(gòu)造函數(shù)" << std::endl; }
// 復(fù)制構(gòu)造函數(shù)
A(A & a) { std::cout << "A 復(fù)制構(gòu)造函數(shù)" << std::endl; }
};
class B
{
// 若沒有聲明構(gòu)造函數(shù)和復(fù)制構(gòu)造函數(shù),則編譯器會默認(rèn)生成構(gòu)造函數(shù)和復(fù)制構(gòu)造函數(shù)
A a; // 成員對象
};
int main()
{
B b1; // b1對象 和 成員對象a都會執(zhí)行無參數(shù)的構(gòu)造函數(shù)
B b2(b1); // b2對象 和 成員對象a都會執(zhí)行復(fù)制構(gòu)造函數(shù)
return 0;
}
輸出結(jié)果:
A 構(gòu)造函數(shù)
A 復(fù)制構(gòu)造函數(shù)