将继承更改为虚拟的后果?

The*_*ist 9 c++ inheritance class multiple-inheritance diamond-problem

我正在做一个我没有开始的大项目.我的任务是为已有的功能添加一些额外的功能.我处于一种必须使用虚拟继承的情况,因为我有一个钻石模型.情况如下图所示:

     Base class
    /           \
   /             \
My new class      A class that was there before (OldClass)
   \             /
    \           /
     \         /
      \       /
    My other new class
Run Code Online (Sandbox Code Playgroud)

为了实现这一点,中间的两个类都必须从基础继承,public virtual而不是仅仅public.所以:

class OldClass: public BaseClass {}
Run Code Online (Sandbox Code Playgroud)

必须成为:

class OldClass: public virtual BaseClass {}
Run Code Online (Sandbox Code Playgroud)

由于这个项目非常庞大,我正在研究它的一小部分,我不想通过这样做来打破它.我的adhoc测试工作,程序似乎工作正常,但我仍然怀疑.

所以我的问题是:通过添加virtual关键字,我应该期待哪些副作用和后果?有什么值得担心的吗?

Sim*_*ter 7

直接后果是,对于常规继承,派生类调用直接基础的构造函数,而对于虚拟继承,最派生类(即直接实例化的类)确实如此,因为这是唯一知道所有虚拟的地方基地.

相比:

struct A { A(int) { } };
struct B : A { B(int i) : A(i) { } };
struct C : B { C(int i) : B(i) { } };
Run Code Online (Sandbox Code Playgroud)

VS

struct A { A(int) { } };
struct B : virtual A { B(int i) : A(i) { } };
// wrong: struct C : B { C(int i) : B(i) { } };
struct C : B { C(int i) : A(i), B(i) { } }; // correct
Run Code Online (Sandbox Code Playgroud)

此外,初始化器行为是不同的,因为如果不是最派生的类A,B则忽略in 的初始化器B:

struct A { A(int i) { cout << 'A' << i; } };
struct B : virtual A { B(int i) : A(i+1) { cout << 'B' << i; } };
struct C : B { C(int i) : A(i+1), B(i+1) { cout << 'C' << i; } };

A a(0);        // prints A0
B b(0);        // prints A1B0
C c(0);        // prints A1B1C0
Run Code Online (Sandbox Code Playgroud)

如果你在这里有非虚拟继承(这将强制你删除构造A函数中的初始化程序C,第三行将输出A2B1C0.