繼承
1. 什麼是繼承
概念:繼承是物件導向程式設計中的一個核心概念,允許一個類(派生類或子類)繼承另一個類(基類或父類)的屬性和方法。
原理:繼承提供了程式碼複用機制,派生類可以擴充套件或修改基類的行為。
用法:使用class Derived : public Base
宣告派生類繼承基類。
案例程式碼:
class Base {
public:
void show() {
cout << "Base class show()" << endl;
}
};
class Derived : public Base {
public:
void show() {
cout << "Derived class show()" << endl;
}
};
int main() {
Derived d;
d.show(); // 輸出 Derived class show()
return 0;
}
2. 繼承的特性
傳遞性:如果類B繼承自類A,類C繼承自類B,則類C間接繼承自類A。
不對稱性:繼承關係不是雙向的,即派生類可以訪問基類的公有成員,但基類不能訪問派生類的成員。
3. 繼承的分類
單繼承:一個類只繼承一個基類。
多繼承:一個類繼承多個基類。
4. 基類成員呼叫的函式的二義性問題
概念:當派生類與基類有同名函式時,會產生呼叫哪個函式的二義性問題。
用法:透過使用作用域解析運算子::
或在派生類中重寫基類函式來解決。
5. 菱形繼承
概念:當兩個基類繼承自同一個基類,而派生類又繼承這兩個基類時,會產生菱形繼承問題。
問題:可能導致基類部分被例項化多次,造成資源浪費。
6. 解決菱形繼承
虛繼承:使用虛繼承可以確保基類只被例項化一次。
案例程式碼:
class Base {};
class Left : virtual public Base {};
class Right : virtual public Base {};
class Derived : public Left, public Right {};
int main() {
Derived d;
return 0;
}
7. 不可被繼承
概念:建構函式、複製建構函式、解構函式、友元和靜態成員不能被繼承。
原理:這些成員與類的具體實現細節相關,不適合被繼承。
8. 繼承方式
public:基類的公有成員和保護成員在派生類中保持原有的訪問許可權。
private:基類的公有成員和保護成員在派生類中變為私有成員。
protected:基類的公有成員和保護成員在派生類中變為受保護成員。
9. 繼承後的訪問許可權
概念:繼承不會改變基類成員的訪問許可權。
原理:派生類可以訪問基類的公有成員和保護成員,但不能訪問基類的私有成員。
10. 繼承的構造、析構順序
構造順序:基類的建構函式先於派生類的建構函式執行。
析構順序:派生類的解構函式先於基類的解構函式執行。
11. 繼承與組合類
概念:在派生類中,基類物件作為成員變數被包含。
構造順序:成員物件的建構函式在派生類建構函式中先執行。
12. 模板的繼承
概念:模板類可以被繼承。
用法:派生類需要指定模板引數以匹配基類。
13. 基類的靜態成員被繼承的特性
概念:靜態成員不屬於類的任何物件,因此不能被繼承。
原理:派生類可以訪問基類的靜態成員,但它們不屬於派生類。
14. 型別相容性原則
概念:派生類物件可以被當作基類物件使用。
原理:基類指標可以指向派生類物件,這是多型的基礎。
15. 隱藏與重定義
隱藏:派生類中與基類同名的函式會隱藏基類中的同名函式。
重定義:派生類可以重寫基類的虛擬函式,以提供特定的實現。
案例程式碼:
class Base {
public:
virtual void func() {
cout << "Base::func()" << endl;
}
};
class Derived : public Base {
public:
void func() {
cout << "Derived::func()" << endl;
}
};
int main() {
Base* b = new Derived();
b->func(); // 輸出 Derived::func()
delete b;
return 0;
}
繼承是物件導向程式設計中實現程式碼複用和擴充套件功能的重要機制。正確使用繼承可以提高程式碼的可維護性和可擴充套件性。