c++菱形繼承產生的問題及解決
阿新 • • 發佈:2019-01-06
#include<stdio.h> #include<iostream> #include<queue> using namespace std; class A { public: A(){printf("A create.\n");} int a; virtual void fun(){} }; class B: public A{ public: B(){printf("B create.\n");} int b; virtual void fun1(){} }; class C: public A { public : int c; C(){printf("C create.\n");} virtual void fun3(){printf("fun3 .\n");} }; class D:public C,public B{ public: int d; D(){printf("D create.\n");} virtual void fun3(){printf("fun4 .\n");} }; //二義性問題的開銷 int main() { D *pd=new D; printf("%d\n",sizeof(D)); getchar(); }
兩個子類繼承同一個父類,而又有子類又分別繼承這兩個子類,會產生二義性問題,此時的繼承關係是這樣的: A A | | B C
\ /
D
相當於baseClass A在類中有兩個,這可能不是我們想要的結果,增加呼叫的困難,同時也會浪費記憶體資源。
那怎麼解決這種問題呢?使用虛擬繼承!
此時,baseClass A是公用的,也就是baseClass A就例項化了一個物件!#include<iostream> using namespace std; class A{ public: A(char *s) { cout<<s<<endl; } ~A(){} }; class B:virtual public A { public: B(char *s1,char*s2):A(s1){ cout<<s2<<endl; } }; class C:virtual public A { public: C(char *s1,char*s2):A(s1){ cout<<s2<<endl; } }; class D:public B,public C { public: D(char *s1,char *s2,char *s3,char *s4):B(s1,s2),C(s1,s3),A(s1) { cout<<s4<<endl; } }; int main() { D *p=new D("class A","class B","class C","class D"); delete p; return 0; }
A
/ \ B C \ /
D 加了virtual後, 繼承關係是這樣的.