菱形继承概念:
两个派生类继承同一个基类 又有某个类同时继承者两个派生类 这种继承被称为菱形继承,或者钻石继承
典型的菱形继承案例:
菱形继承问题:
#include<iostream> #include<string> using namespace std; class animal//父类 { public: int m_age; }; class sheep:public animal //sheep继承了animal 类 { }; class tuo:public animal //tuo也继承了animal 类 { }; class sheeptuo :public sheep, public tuo //sheeptuo 又多继承了sheep 和 tuo 类 { }; void main() { sheeptuo s; //s.m_age;//不明确 cout << "sheeptuo所占空间:" << sizeof(sheeptuo) << endl; //8 因为继承了两个age s.sheep::m_age = 200; s.tuo::m_age = 300; cout << "sheep中age:" << s.sheep::m_age << endl; cout << "tuo中age:" << s.tuo::m_age << endl; }
#include<iostream> #include<string> using namespace std; class animal//父类 { public: int m_age; }; //继承前加virtual关键字后,变为虚继承 //此时公共的父类Animal称为虚基类 class sheep:virtual public animal //sheep继承了animal 类,虚继承 { }; class tuo:virtual public animal //tuo也继承了animal 类,虚继承 { }; class sheeptuo :public sheep, public tuo //sheeptuo 又多继承了sheep 和 tuo 类 { }; void main() { sheeptuo s; //12字节 因为继承了一个age,使用虚继承又增加了两个指针,两个指针都指向age这个变量;所有的age都是同一个,都是在对同一个数据操作 cout << "sheeptuo所占空间:" << sizeof(sheeptuo) << endl; s.sheep::m_age = 200; s.tuo::m_age = 300; //以最后的赋值数据为准,之前的都被覆盖 cout << "sheep中age:" << s.sheep::m_age << endl; cout << "tuo中age:" << s.tuo::m_age << endl; cout << "sheeptuo中age:" << s.m_age << endl; }
增加了两个vbptr指针, v:virtual b:base ptr:pointer
vbptr指向vbtable虚基类表,第一个vbptr指向 sheep的虚基类表,偏移量为8,偏移量加8之后就找到了age这个变量;第二个vbptr指向 tuo的虚基类表,偏移量为4,偏移量加4之后就找到了age这个变量;他们指向的都是同一个变量。