多继承和虚继承
1、多继承的优缺点
(1) 多继承可以复用多个类的代码(函数,变量)。
(2) 多继承会带来二义性问题。
// 1. 多继承优缺点 class Flyable { public: void fly() { cout << "飞翔..." << endl; } void sound() { cout << "嗖嗖..." << endl; } }; class Runnable { public: void run() { cout << "跑步..." << endl; } void sound() { cout << "刺啦..." << endl; } }; class SuperMan : public Flyable, public Runnable {}; void test01() { SuperMan sm; sm.fly(); sm.run(); // 1. 多继承可以复用多个类的代码(函数、 变量) // 2. 多继承带来二义性问题. // sm.sound(); sm.Flyable::sound(); sm.Runnable::sound(); }
2、菱形继承问题
1、菱形问题会造成空间浪费。
2、菱形继承问题会产生二义性。
// 2. 菱形继承问题 class Animal { public: int m_animal; }; class Sheep : public Animal { public: int m_sheep; }; class Tuo : public Animal { public: int m_tuo; }; class SheepTuo : public Sheep, public Tuo { }; void test02() { // 1. 空间浪费 // 2. 二义性 SheepTuo st; // st.m_animal; }
3、虚继承
(1) 当发生虚继承的时候,编译器会在子类中安插一个vbptr指针。
(2) 指针指向一张记录着公共数据相对于vbptr指针的偏移量。
(3) 根据偏移量就可以找到公共部分的数据。
(4) 虚继承会带来程序额外的开销,但是解决了菱形继承的问题。
(5) 虚继承中C++编译器要求没一个子类都能够初始化虚基类数据。
(6) 虚继承主要是为了解决菱形继承问题,如果没有发生菱形继承问题,不建议使用虚继承。
(7) 不建议大家大量使用多继承,允许多接口继承一般不会多继承(任何多继承问题都可以用单继承来解决)
// 3. 虚继承 使用virtual关键字 class Animal { public: Animal(int) { } public: int m_animal; }; class Sheep : virtual public Animal { public: Sheep() : Animal(10) {} public: int m_sheep; }; class Tuo : virtual public Animal { public: Tuo() : Animal(10) {} public: int m_tuo; }; class SheepTuo : public Sheep, public Tuo { public: SheepTuo() : Animal(10) {} }; void test03() { SheepTuo st; st.m_animal; st.Sheep::m_animal; st.Tuo::m_animal; Sheep s; s.m_animal; }