定义
关于多重继承,考虑如下的情形:
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%程度上,你的类设计有误(?)。
初始化
虚基类由最低层派生类的构造函数初始化(如果由直接派生类初始化,则基类可能被多次重复初始化)。
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
基类析构函数的调用顺序总是与构造函数调用顺序相反。
C++ Primer 17.3.5

625

被折叠的 条评论
为什么被折叠?



