多繼承 與 多重繼承
多繼承
多繼承是指一個子類繼承多個父類。多繼承對父類的個數沒有限制,繼承方式可以是公共繼承、保護繼承和私有繼承。不寫繼承方式,預設是私有繼承。
多繼承下派生類的定義格式如下:
class A
{
…
};
class B
{
…
};
class C : <繼承方式> public A, <繼承方式> public B
{
…
};
按照繼承的規定,派生類 C 的成員包含了基類 A、B 中成員以及該類本身的成員。
派生類建構函式執行順序是先執行所屬基類的建構函式,再執行派生類本身建構函式,處於同一層次的各基類建構函式的執行順序取決於定義派生類時所指定的各基類順序,與派生類建構函式中所定義的成員初始化列表的各項順序無關。
下面通過一個例子來說明派生類建構函式的構成及其執行順序:
#include <iostream.h>
class B1
{
public:
B1(int i)
{
b1 = i;
cout<<"建構函式 B1."<<i<< endl;
}
void print()
{
cout<<"B1.print()"<<b1<<endl;
}
private:
int b1;
};
class B2
{
public:
B2(int i)
{
b2 = i;
cout<<"建構函式 B2."<<i<< endl;
}
void print()
{
cout<<"B2.print()"<<b2<<endl;
}
private:
int b2;
};
class B3
{
public:
B3(int i)
{
b3 = i;
cout<<"建構函式 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 的引數列表必須包含後面繼承的所有基類的引數
{
a = l;
cout<<"建構函式 A."<<a<<endl;
}
void print()
{
B1::print();
B2::print();
cout<<"A.print()"<<a<<","<<bb.getb3()<<endl;
}
private:
int a;
B3 bb;
};
void main()
{
A aa(1, 2, 3, 4);
aa.print();
}
該程式的輸出結果為:
建構函式 B2.2
建構函式 B1.1
建構函式 B3.3
建構函式 A.4
B1.print()1
B2.print()2
A.print()4,3
在該程式中,作用域運算子 ::
用於解決作用域衝突的問題。在派生類 A 中的 print() 函式的定義中,使用了 B1::print;
和 B2::print();
語句分別指明呼叫哪一個類中的 print() 函式,否則會出現二義性問題。
如果是基類和派生類中出現同名函式,不存在二義性問題,規定派生類的成員將支配基類中的同名成員,即派生類的物件只會使用派生類的該函式。
當一個派生類 C 從多個基類派生(B1、B2...),而這些基類又有一個共同的基類 A,則對該 A 類中宣告的成員進行訪問時,也可能會出現二義性。應以作用域 B1::
或 B2::
等來限定。
由於二義性的原因,一個類不可以從同一個類中直接繼承一次以上,例如:
class A : public B, public B // 這是錯誤的
{
…
}
多重繼承
當 B 類從 A 類派生,C 類從 B 類派生,此時稱為多重繼承。
當例項化子類時,會首先依次呼叫所有基類的建構函式,最後呼叫該子類的建構函式;銷燬該子類時則相反,先呼叫該子類的解構函式,再依次呼叫所有基類的解構函式。
無論繼承的層級有多少層,子類都可以與其直接父類或間接父類構成 “is a” 的關係,並且能夠通過父類的指標對直接子類或間接子類進行相應的操作,子類物件可以給直接父類或間接父類的物件或引用賦值或初始化。
相關文章
- C++ 多級繼承與多重繼承:程式碼組織與靈活性的平衡C++繼承
- 繼承與多型繼承多型
- odoo 繼承(owl繼承、web繼承、view繼承)Odoo繼承WebView
- 多繼承繼承
- 聊聊iOS中的多繼承和多重代理iOS繼承
- java繼承與多型Java繼承多型
- day23:單繼承&多繼承&菱形繼承&__init__魔術方法繼承
- python 基礎之繼承、重寫、多繼承Python繼承
- 菱形繼承,虛繼承繼承
- 原型,繼承——原型繼承原型繼承
- JavaScript 的繼承與多型JavaScript繼承多型
- Javascript的繼承與多型JavaScript繼承多型
- C#如何實現多重繼承C#繼承
- 多型和繼承多型繼承
- Javascript繼承2:建立即繼承—-建構函式繼承JavaScript繼承函式
- Javascript繼承4:潔淨的繼承者—-原型式繼承JavaScript繼承原型
- python3 筆記20.類的呼叫和多重繼承(多重繼承MRO方法解析順序)Python筆記繼承
- Python多重繼承注意事項!Python教程Python繼承
- Python的多重繼承如何使用?python教程Python繼承
- 繼承繼承
- Maven 聚合與繼承Maven繼承
- C++中公有繼承、保護繼承、私有繼承的區別C++繼承
- Python 繼承 和 多型Python繼承多型
- Java中的類繼承與多型Java繼承多型
- 類的繼承_子類繼承父類繼承
- JavaScript繼承JavaScript繼承
- javascript:繼承JavaScript繼承
- python繼承Python繼承
- JavaScript 繼承JavaScript繼承
- 10 #### 繼承繼承
- python 繼承Python繼承
- javascript - 繼承與原型鏈JavaScript繼承原型
- class語法與繼承繼承
- 原型、原型鏈與繼承原型繼承
- 繼承(extends)與介面( implements)繼承
- 封裝、繼承和多型封裝繼承多型
- TypeScript(5)類、繼承、多型TypeScript繼承多型
- OOP的多型和繼承OOP多型繼承