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关键字,我应该期待哪些副作用和后果?有什么值得担心的吗?
直接后果是,对于常规继承,派生类调用直接基础的构造函数,而对于虚拟继承,最派生类(即直接实例化的类)确实如此,因为这是唯一知道所有虚拟的地方基地.
相比:
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.