繼承與派生(3):多繼承
多繼承可以看作是單繼承的擴 展。所謂多繼承是指派生類具有多個基類,派生類與每個基類之間的關係仍可看作是一個單繼承。
• 多繼承是指派生類可以有一個以上的直接基類。多繼承的派 生類定義格式為:
class <派生類名>: [<繼承方式>] <基類名1>,
[<繼承方式>] <基類名2>,…
{
<成員說明表>
};
– 繼承方式及訪問控制的規定同單繼承。
– 派生類擁有所有基類的所有成員。
– 基類的宣告次序決定: • 對基類建構函式/解構函式的呼叫次序 • 對基類資料成員的儲存安排。
例如:
class A { … };
class B { … };
class C : public A, public, B { … };
其中,派生類C具有兩個基類(類A和類B),因此,類C 是多繼承的。按照繼承的規定,派生類C的成員包含了 基類A,B中成員以及該類本身的成員。
• 建構函式的執行次序是: – A()、B()、C() (A()和B()實際是在C()的成員初始 化表中呼叫。)
• 下面的操作是合法的: c.fa(); c.fb(); c.fc();
多繼承的建構函式
多繼承的情況下,派生類的建構函式格式如下:
<派生類名>(<總引數表>):<基類名1>(<引數表1>), <基類 名2>(<引數表2>),…<子物件名>(<引數表n+1>),…
{ <派生類建構函式體> }
其中,<總引數表>中各個引數包含了其後的各個分引數表。
多繼承下派生類的建構函式與單繼承下派生類構造函 數相似,它必須同時負責該派生類所有基類建構函式的呼叫。同時,派生類的引數個數必須包含完成所有基類初始 化所需的引數個數。
派生類建構函式執行順序是:
1、先執行所有基類的建構函式,
2、再執行派生類本身建構函式,
3、處於同一層次的各基類建構函式的執行順序取決於 定義派生類時所指定的各基類順序,與派生類建構函式 中所定義的成員初始化列表的各項順序無關。 也就是說,執行基類建構函式的順序取決於定義派 生類時基類的順序。可見,派生類建構函式的成員初始 化列表中各項順序可以任意地排列。
#include <iostream>
using namespace std;
class B1 //基類B1
{ public:
B1(int i)
{b1=i; cout<<"constructor B1."<<i<<endl;}
void print()
{cout<<b1<<endl;}
private:
int b1;
};
class B2 //基類B2
{ public:
B2(int i) { b2=i; cout<<"constructor B2."<<i<<endl;}
void print(){cout<<b2<<endl;}
private:
int b2;
};
class B3 //成員類B3
{ public:
B3(int i)
{ b3=i; cout<<"constructor B3."<<i<<endl;}
int getb3(){return b3;}
private:
int b3;
};
class A : public B2, public B1 //注意基類的順序,呼叫建構函式的順序
{ public:
A(int i, int j, int k, int l) : B1(i), B2(j), bb(k)
{ a=l; cout<<"constructor A."<<l<<endl; }
void print() { B1::print(); B2::print(); cout<<a<<", "<<bb.getb3()<<endl; }
private:
int a;
B3 bb;
};
int main()
{
A aa(1,2,3,4);
aa.print();
return 0;
}
執行結果: