C++多態、虛函數、純虛函數、抽象類、虛基類
一、C++多態
C++的多態包括靜態多態和動態多態。靜態多態包括函數重載和泛型編程,動態多態包括虛函數。靜態多態是指在編譯期間就可以確定,動態多態是指在程序運行時才能確定。
二、虛函數
1、虛函數為類的非靜態成員函數,訪問權限一般為public。函數聲明時,在返回值前加virtual關鍵字,函數定義時不需要加virtual。父類定義的虛函數,子類在繼承時,可以對虛函數重新定義,當然子類的函數應該與父類虛函數一樣,只是函數實現不一樣。我們用父類的指針指向子類的實例,然後通過父類的指針可以調用實際子類的成員函數。
2、構造函數不能為虛函數
3、當基類中有虛函數的時候,一般基類的析構函數也要定義為虛析構函數。如果不定義虛析構函數,當刪除一個指向派生類對象的指針時,會調用基類的析構函數,派生類的析構函數未被調用,造成內存泄漏。定義虛析構函數後,最底層的派生類的析構函數最先被調用,然後各個基類的析構函數被調用。
三、純虛函數
純虛函數為虛函數在聲明時,函數末尾加=0,純虛函數沒有函數定義,它的子類需要繼承所有基類的純虛函數並且給出定義。純虛函數的作用就是為派生類提供一個一致的接口。
四、抽象類
抽象類就是指含有純虛函數的類,該類不能創建對象,但是可以聲明指針和引用。
五、虛基類
1、如果一個派生類有多個直接基類,而這些直接基類又有一個共同的基類,則在最終的派生類中會保留該間接共同基類數據成員的多份同名成員。在引用這些同名的成員時,必須在派生類對象名後增加直接基類名,以避免二義性。
示例:
class A
{
public:
int m_nNum;
};
class B :public A
{…};
class C :public A
{…};
class D :public B,public C
{
};
D d1;
d1.A::m_nNum;
2、C++提供虛基類,使得在繼承間接共同基類時只保留一份成員。
示例:
class A
{
public:
int m_nNum;
};
class B :virtual public A
{…};
class C :virtual public A
{…};
class D :public B,public C
{
};
D d1;
d1.m_nNum;
3、在最後的派生類中不僅要負責對直接基類進行初始化,還要負責對虛基類初始化。C++編譯系統只執行最後的派生類對虛基類的構造函數的調用,而忽略虛基類的其他派生類(B和C)對虛基類的構造函數的調用,保證了虛基類成員不會被多次初始化。
例如:
class D :public B,public C
{
D(int n):A(n),B(n),C(n){ }
};
構造的順序為先構造最上層基類,然後父類誰先繼承誰先構造,析構函數的順序和構造函數順序相反。
C++多態、虛函數、純虛函數、抽象類、虛基類