据我所知,虚拟基类机制的存在是为了防止" Diamond"问题。但我很好奇是否通过重新设计类层次结构来更好地处理这种情况。 请参考以下案例:copied from here
class A { public: void Foo() {} };
class B : public virtual A {};
class C : public virtual A {};
class D : public B, public C {};
我现在看到的机制存在的问题是,你需要能够预测某人会出现并从B和C继承。所以并不意味着我们最好用标记每个继承虚拟?
答案 0 :(得分:3)
类A
的虚拟继承意味着
A
必须在派生程度最高的类中初始化,A
事物的访问变得效率稍低(因为A
子对象可以在几个派生类对象之间共享,因此可以在每个对象中处于动态偏移量。)由于这些原因,使用虚拟继承时非常谨慎。
一个好的经验法则是对接口使用虚拟继承,而不是对实现类使用。
答案 1 :(得分:3)
您可以在virtual
成员函数上争论同一点 - 为什么不使所有成员函数virtual
,因为如果有人出现并继承自class
他们可能希望能够覆盖您的成员函数。我们不这样做,因为对于virtual
基类,virtual
成员函数具有与它们相关联的额外成本(在时间/资源开销和复杂性方面)。
答案 2 :(得分:0)
虚拟继承是所有具有多重继承功能的语言中必不可少的功能。虽然所有继承案例都可能是虚拟的,但这有:
这是因为虚拟继承是继承的一种特殊情况,其中继承是直接派生类的指令,而不是类本身。结果,每个派生另一个类虚拟的基类都将此虚拟基础作为直接基类提供给每个下一个派生类。当然,如果多个基类提供相同的虚基类,它会导致一次由派生类派生,但这是因为这些多个基类提供了多个派生指令,但是一个类(与正常继承相反,哪个case基类将提供多个基类的子对象。)
它始终是直接基类这一事实的结果是要求它在每个下一个派生类中显式构造。当然,默认构造函数规则适用,但C ++在此规则中甚至不会产生 - 接受基类初始化虚拟基础的代码;唯一被拒绝的情况是虚拟基础在多个基类中“竞争初始化” - 在这种情况下,您必须通过提供构造规范来“解决冲突”。
请不要因为蹩脚的自我推销而抨击我,但我在这里更详细地描述了这个话题:
https://sektorvanskijlen.wordpress.com/2010/12/08/multiple-inheritance-considered-nice