[C++] 虚拟继承

定义

关于多重继承,考虑如下的情形:

class A { public: void Foo() {} };
class B : public A {};
class C : public A {};
class D : public B, public C {};

以上类的继承层次关系形成一个“可怕的钻石”,如左图, 但内存布局如右图, D有两份A的“实例”(仅为形象表述)

    A                                                    A    A   

  /  \                                                    |      |

B     C     ----- Memory Layout ---->       B     C 

  \  /                                                     \   /

   D                                                        D

当要调用 D::Foo()时, 就会出现二义性问题:

D d;
d.Foo(); // is this B's Foo() or C's Foo() ??

解决方法是使用虚拟继承,相当于告诉编译器,只要一份A的“实例”:

class A { public: void Foo() {} };
class B : public virtual A {};
class C : public virtual A {};
class D : public B, public C {};

然后就可以正常调用 D::Foo()

D d;
d.Foo(); // no longer ambiguous
如果类的继承关系出现了这种钻石结构,在95%程度上,你的类设计有误(?)。


扫描二维码关注公众号,回复: 583742 查看本文章

初始化

虚基类由最低层派生类的构造函数初始化(如果由直接派生类初始化,则基类可能被多次重复初始化)。

                ZooAnimal

             virtual /       \ virtual      

                Bear  Raccoon  Endangered

                      \           |          /
                            
                                          Panda

Bear::Bear(std::string name, bool onExhibit):
             ZooAnimal(name, onExhibit, "Bear") { }
Raccoon::Raccoon(std::string name, bool onExhibit)
           : ZooAnimal(name, onExhibit, "Raccoon") { }

// ZooAnimal 由 Panda 的构造函数初始化:
Panda::Panda(std::string name, bool onExhibit)
          : ZooAnimal(name, onExhibit, "Panda"),
            Bear(name, onExhibit),
            Raccoon(name, onExhibit),
            Endangered(Endangered::critical),
            sleeping_flag(false) { }

如果有以下类:

class Character { /* ... */ };
class BookCharacter : public Character { /* ... */ };
class ToyAnimal { /* ... */ };
class TeddyBear : public BookCharacter,
                     public Bear, public virtual ToyAnimal
                     { /* ... */ };

则构造函数调用顺序如下:

ZooAnimal();           // Bear's virtual base class
    ToyAnimal();       // immediate virtual base class
    Character();       // BookCharacter's nonvirtual base class
    BookCharacter();   // immediate nonvirtual base class
    Bear();            // immediate nonvirtual base class
    TeddyBear();       // most derived class
基类析构函数的调用顺序总是与构造函数调用顺序相反。



What is a virtual base class?

Virtual inheritance

Virtual inheritance in C++

C++ Primer 17.3.5

猜你喜欢

转载自blog.csdn.net/ftell/article/details/80177962