菱形虛擬繼承
菱形繼承(也叫鉆石繼承)
結構如下
#include <iostream> using namespace std; class AA { public: int _aa; }; class BB:public AA { public: int _bb; }; class CC:public AA { public: int _cc; }; class DD:public BB,public CC { public: int _dd; }; 代碼中DD所對應的模型為 ![]()
菱形繼承帶來二義性和數據冗余的問題,為了解決菱形繼承數據冗余的問題,引入虛繼承。
#include <iostream> using namespace std; class AA { public: int _aa; }; class BB:virtual public AA { public: int _bb; }; class CC:virtual public AA { public: int _cc; }; class DD:public BB,public CC { public: int _dd; }; int main(){ DD d; d.BB::_aa = 0; d._bb = 1; d.CC::_aa = 2; d._cc = 3; d._dd = 4; cout << sizeof(DD) << endl; system("pause"); return 0;}![]()
在這里BB、CC的第一個字節保存的是一個地址,地址存放偏移地址。
所謂多態,其實就是“多種形態”。
C++中虛函數的主要作用就是實現多態。簡單說父類的指針/引用調用重寫的虛函數,當父類指針/引用指向父類對象時調用的是父類的虛函數,指向子類對象時調用的是子類的虛函數。
虛函數實現多態的條件
被virtual關鍵字修飾的成員函數,就是虛函數。虛函數只能是類中成員函數,且不能是靜態的。
class 類名 {
...
virtual 返回類型 函數名(形式參數列表);//虛函數
...
};
virtual只能在類體中使用。若在類外定義虛函數,則只能在聲明函數時加 virtua,類外定義函數時不能加virtual。
當派生類中定義的成員函數的參數個數、參數類型、返回值類型與基類中同名的虛函數完全一樣,則派生類的這個成員函數無論加不加virtual,它都是一個虛函數。
為了便于閱讀,一般給派生類的同名函數也加上virtual。
構造函數不能味虛函數,雖然可以將Operator=定義為虛函數,但其在使用時容易引起混淆。
不要在構造函數和析構函數里面調用虛函數。
基類的析構函數最好聲明為虛函數。
#include <iostream>using namespace std;class Base{public: virtual void Fun1() { cout << "Base::Fun1()" << endl; } virtual void Fun2() //關鍵字virtual { cout << "Base::Fun2()" << endl; }};class Derived: public Base{public: virtual void Fun3() //關鍵字virtual { cout << "Derived::Fun3()" << endl; } virtual void Fun4() //關鍵字virtual { cout << "Derived::Fun4()" << endl; }}; 菱形虛擬繼承
新聞熱點
疑難解答