将继承更改为虚拟的后果? [英] Consequences of changing inheritance to virtual?

查看:120
本文介绍了将继承更改为虚拟的后果?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm working on a huge project that I didn't start. My task is to add some additional functionality to what already is there. I'm in a situation where I have to use virtual inheritance because I have a diamond model. The situation is depicted in the following illustration:

     Base class
    /           \
   /             \
My new class      A class that was there before (OldClass)
   \             /
    \           /
     \         /
      \       /
    My other new class

为此,中间的两个类必须通过公共虚拟从基地继承,而不仅仅是公共。所以:

For this to work, both the classes in the middle have to inherit from the base through public virtual instead of just public. So:

class OldClass: public BaseClass {}

必须成为:

class OldClass: public virtual BaseClass {}

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

Since this project is really huge and I'm working on a small part of it, I don't want to break it by doing this. My adhoc tests worked and the program seems to work fine, but I'm still skeptic.

所以我的问题是:我应该通过添加虚拟关键字?有什么可担心的吗?

So my question is: What side effects and consequences should I expect by adding the virtual keyword? Is there anything to worry about?

推荐答案

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

The immediate consequence is that for regular inheritance, derived classes invoke the constructor of the immediate base, while for virtual inheritance, the most derived class (i.e. the one being instantiated directly) does, as this is the only place that would know all the virtual bases.

比较:

struct A { A(int) { } };
struct B : A { B(int i) : A(i) { } };
struct C : B { C(int i) : B(i) { } };

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

此外,初始化程序行为也不同,因为的初始化程序如果 B 不是派生程度最高的类,则忽略 B 中的

Also, the initializer behaviour is different, because the initializer for A in B is ignored if B is not the most derived class:

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

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

If you had non-virtual inheritance here (which would force you to remove the A initializer in the C constructor, the third line would output A2B1C0.

这篇关于将继承更改为虚拟的后果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆