繼承裡既有虛繼承也有虛擬函式繼承(即既有虛基表,也有虛擬函式表)
阿新 • • 發佈:2018-10-31
對於單一的虛繼承可參考這篇部落格:
https://blog.csdn.net/sophia__yu/article/details/82791522
對於有虛擬函式繼承可參考這篇部落格:
https://blog.csdn.net/sophia__yu/article/details/82791592
接下來將會介紹既有虛繼承也有多型的繼承:
首先看程式碼:
#include<stdio.h> #include<iostream> #include<string> using namespace std; /////////////虛基表和虛表 class A { public: virtual void f1() { cout << "A::f1()" << endl; } virtual void f2() { cout << "A::f2()" << endl; } public: int _a; }; class B :virtual public A { public: virtual void f1() //重寫虛擬函式 { cout << "B::f1 ()" << endl; } virtual void f3() // B重新定義的虛擬函式 { cout << "B::f3()" << endl; } //另外B繼承了A的f2函式 public: int _b; }; class C : virtual public A { public: virtual void f1() // C重寫了虛擬函式f1 { cout << "C::f1()" << endl; } virtual void f3() // C重新定義了虛擬函式f3 { cout << "C::f3()" << endl; } //另外C繼承了A的虛擬函式f2 public: int _c; }; class D : public B, public C { public: virtual void f1() { cout << "D::f1()" << endl; } virtual void f4() { cout << "D::f4()" << endl; } public: int _d; }; typedef void(*FUNC)(); void printVtable(int *vfter) { cout << "虛表地址:" << vfter << endl; for (int i = 0; vfter[i] != 0; i++) //因為虛表最後一個元素是0 { printf("第%d個虛擬函式地址:0x%x,->", i, vfter[i]); FUNC f = (FUNC)vfter[i]; f(); //呼叫該虛擬函式 } cout << endl; } int main() { D d; d._a = 1; d._b = 2; d._c = 3; d._d = 4; cout << sizeof(d) << endl; int *vfptr1 = (int*)(*((int*)(&d))); //B 的虛表指標 printVtable(vfptr1); int *vfptr2 = (int*)(*((int*)(((char*)(&d)) + 12)));// C的虛表指標 printVtable(vfptr2); int *vfptr = (int*)(*((int*)(((char*)(&d)) + 28))); // 公共虛表指標 printVtable(vfptr); system("pause"); return 0; }
具體解釋如下:
注:主要是在A類中,不論是不是冗餘資料,都要放在公共資料塊即最下邊(相對編譯器)。