C++多繼承(多重繼承)
阿新 • • 發佈:2022-11-29
派生類都只有一個基類,稱為單繼承(Single Inheritance)。除此之外,C++也支援多繼承(Multiple Inheritance),即一個派生類可以有兩個或多個基類。
多繼承形式下的建構函式和單繼承形式基本相同,只是要在派生類的建構函式中呼叫多個基類的建構函式。以上面的 A、B、C、D 類為例,D 類建構函式的寫法為:
下面是一個多繼承的例項:
BaseA constructor
BaseB constructor
Derived constructor
1, 2, 3, 4, 5
Derived destructor
BaseB destructor
BaseA destructor
從執行結果中還可以發現,多繼承形式下解構函式的執行順序和建構函式的執行順序相反。
修改上面的程式碼,為 BaseA 和 BaseB 類新增 show() 函式,並將 Derived 類的 show() 函式更名為 display():
多繼承容易讓程式碼邏輯複雜、思路混亂,一直備受爭議,中小型專案中較少使用,後來的 Java、C#、PHP 等乾脆取消了多繼承。多繼承的語法也很簡單,將多個基類用逗號隔開即可。例如已聲明瞭類A、類B和類C,那麼可以這樣來宣告派生類D:
class D: public A, private B, protected C{
//類D新增加的成員
}
多繼承下的建構函式
D(形參列表): A(實參列表), B(實參列表), C(實參列表){
//其他操作
}
D(形參列表): B(實參列表), C(實參列表), A(實參列表){
//其他操作
}
下面是一個多繼承的例項:
- #include <iostream>
- using namespace std;
- //基類
- class BaseA{
- public:
- BaseA(int a, int b);
- ~BaseA();
- protected:
- int m_a;
- int m_b;
- };
- BaseA::BaseA(int a, int b): m_a(a), m_b(b){
- cout<<"BaseA constructor"<<endl;
- }
- BaseA::~BaseA(){
- cout<<"BaseA destructor"<<endl;
- }
- //基類
- class BaseB{
- public:
- BaseB(int c, int d);
- ~BaseB();
- protected:
- int m_c;
- int m_d;
- };
- BaseB::BaseB(int c, int d): m_c(c), m_d(d){
- cout<<"BaseB constructor"<<endl;
- }
- BaseB::~BaseB(){
- cout<<"BaseB destructor"<<endl;
- }
- //派生類
- class Derived: public BaseA, public BaseB{
- public:
- Derived(int a, int b, int c, int d, int e);
- ~Derived();
- public:
- void show();
- private:
- int m_e;
- };
- Derived::Derived(int a, int b, int c, int d, int e): BaseA(a, b), BaseB(c, d), m_e(e){
- cout<<"Derived constructor"<<endl;
- }
- Derived::~Derived(){
- cout<<"Derived destructor"<<endl;
- }
- void Derived::show(){
- cout<<m_a<<", "<<m_b<<", "<<m_c<<", "<<m_d<<", "<<m_e<<endl;
- }
- int main(){
- Derived obj(1, 2, 3, 4, 5);
- obj.show();
- return 0;
- }
BaseA constructor
BaseB constructor
Derived constructor
1, 2, 3, 4, 5
Derived destructor
BaseB destructor
BaseA destructor
從執行結果中還可以發現,多繼承形式下解構函式的執行順序和建構函式的執行順序相反。
命名衝突
當兩個或多個基類中有同名的成員時,如果直接訪問該成員,就會產生命名衝突,編譯器不知道使用哪個基類的成員。這個時候需要在成員名字前面加上類名和域解析符::
,以顯式地指明到底使用哪個類的成員,消除二義性。修改上面的程式碼,為 BaseA 和 BaseB 類新增 show() 函式,並將 Derived 類的 show() 函式更名為 display():
- #include <iostream>
- using namespace std;
- //基類
- class BaseA{
- public:
- BaseA(int a, int b);
- ~BaseA();
- public:
- void show();
- protected:
- int m_a;
- int m_b;
- };
- BaseA::BaseA(int a, int b): m_a(a), m_b(b){
- cout<<"BaseA constructor"<<endl;
- }
- BaseA::~BaseA(){
- cout<<"BaseA destructor"<<endl;
- }
- void BaseA::show(){
- cout<<"m_a = "<<m_a<<endl;
- cout<<"m_b = "<<m_b<<endl;
- }
- //基類
- class BaseB{
- public:
- BaseB(int c, int d);
- ~BaseB();
- void show();
- protected:
- int m_c;
- int m_d;
- };
- BaseB::BaseB(int c, int d): m_c(c), m_d(d){
- cout<<"BaseB constructor"<<endl;
- }
- BaseB::~BaseB(){
- cout<<"BaseB destructor"<<endl;
- }
- void BaseB::show(){
- cout<<"m_c = "<<m_c<<endl;
- cout<<"m_d = "<<m_d<<endl;
- }
- //派生類
- class Derived: public BaseA, public BaseB{
- public:
- Derived(int a, int b, int c, int d, int e);
- ~Derived();
- public:
- void display();
- private:
- int m_e;
- };
- Derived::Derived(int a, int b, int c, int d, int e): BaseA(a, b), BaseB(c, d), m_e(e){
- cout<<"Derived constructor"<<endl;
- }
- Derived::~Derived(){
- cout<<"Derived destructor"<<endl;
- }
- void Derived::display(){
- BaseA::show(); //呼叫BaseA類的show()函式
- BaseB::show(); //呼叫BaseB類的show()函式
- cout<<"m_e = "<<m_e<<endl;
- }
- int main(){
- Derived obj(1, 2, 3, 4, 5);
- obj.display();
- return 0;
- }