類的組合
1. 定義和描述
組合類構造函數定義(注意不是聲明)的一般形式為:
類名::類名(形參表):內嵌對象1(形參表),內嵌對象2(形參表),...
{
類的初始化
}
其中,“內嵌對象1(形參表),內嵌對象2(形參表),...”成為初始化列表,可以用於完成對內嵌對象的初始化。其實,一般的數據成 員也可以這樣初始化,就是把這裡的內嵌對象都換成一般的數據成員,後面的形參表換成用來的初始化一般數據成員的變量形參,比如 ,Point::Point(int xx, int yy):X(xx),Y(yy) { },這個定義應該怎麼理解呢?就是我們在構造Point類的對象時傳入實參初始化 xx和yy,然後用xx的值初始化Point類的數據成員X,用yy的值初始化數據成員Y。
類的組合其實描述的就是在一個類裡內嵌了其他類的對象作為成員的情況,它們之間的關系是一種包含與被包含的關系。簡單說,一 個類中有若干數據成員是其他類的對象。以前的教程中我們看到的類的數據成員都是基本數據類型的或自定義數據類型的,比如int、 float類型的或結構體類型的,現在我們知道了,數據成員也可以是類類型的。
如果在一個類中內嵌了其他類的對象,那麼創建這個類的對象時,其中的內嵌對象也會被自動創建。因為內嵌對象是組合類的對象的 一部分,所以在構造組合類的對象時不但要對基本數據類型的成員進行初始化,還要對內嵌對象成員進行初始化
2. 構造函數的調用順序
組合類的構造函數的調用順序是根據組合類的初始化列表來一一執行的,按照內嵌對象在組合類的聲明中出現的次序,依次調用內嵌對 象的構造函數,然後再執行本類的構造函數的函數體。如果聲明組合類的對象時沒有指定對象的初始值的話,就會自動調用無形參的構 造函數,構造內嵌對象時也會對應的調用內嵌對象的無形參的構造函數。
Example:
class Point
{
public:
Point(int X, int Y);
private:
int X;
int Y;
}
Point::Point(Point &p)
{
}
class Distance
{
public:
Distance(Point a, Point b);
private:
Point p1, p2;
}
Distance::Distance(Point a, Point b):p1(a), p2(b)
{
}
在Distance中先調用p1的構造函數,再調用p2的構造函數,因為在Distance中內嵌對象Point的聲明順序是p1,p2
3. 類組合的特殊情況
當兩個類相互包含時,即類A有類B的內嵌對象,類B中也有類A的嵌入對象時,在C++中,要使用一個類必須在使用前先聲明該類, 但是兩個類互相包含時就肯定是有一個類在定義之前就被引用了,這時候就要用到 -->前向引用聲明
前向引用聲明是在引用沒有定義的類之前對該類進行聲明,這只是為程序聲明一個代表該類的標識符,類的具體定義可以在程序 的其他地方,簡單說,就是聲明下這個標識符是個類,它的定義你可以在別的地方找到。
Example:
類A的公有成員函數f的形參是類B的對象,同時類B的公有成員函數g的形參是類A的對象,這時就必須使用前向引用聲明:
class B; //前向引用聲明
class A
{
public:
void f(B b);
};
class B
{
public:
void g(A a);
};