A类:公共虚拟B和A类:公共B之间有什么区别

时间:2013-03-19 11:34:57

标签: c++ virtual multiple-inheritance

#include<iostream>
using namespace std;

class base
{
    public:
      virtual void f(){}
};

class middle1:public base
{};

class middle2:public base
{};

class derive:public middle1,public middle2
{};



int main()
{
    derive* pd=new derive();
    pd->f();
    return 0;
}

我知道虚拟解决了这个问题,但是如何解决? 即使我们没有多重继承,我们是否可以始终将公共虚拟写入安全性。

3 个答案:

答案 0 :(得分:2)

derive的每个实例都有一个middle1基类子对象和一个middle2基类子对象。

如果继承是非虚拟的,那么middle1基类子对象有一个base基类子对象, middle2基类子对象还有一个base基类子对象。因此,derive的每个实例都有两个base个子对象,而调用pd->f()是不明确的 - 您要调用哪个base个对象{{1在?

使继承成为虚拟意味着f()middle1将共享middle2base个子对象。这消除了歧义 - 只有一个derive对象可以调用base

  

我们是否可以始终将公共虚拟写入安全

不一定。可能存在继承层次结构,您不希望 {/ em> f()middle1共享公共middle2子对象。您可能会争辩说,在这种情况下,您不应该编写继承自两者的类base,但如果您最终遇到这种情况,则解决方法是执行以下任一操作:

derive

指定要在static_cast<middle1*>(pd)->f(); pd->middle1::f(); 基类子对象上调用f,或

middle1

指定static_cast<middle2*>(pd)->f(); pd->middle2::f();

答案 1 :(得分:1)

  

我知道虚拟解决了这个问题,但是如何解决?

virtual个关键字通过在继承层次结构中只存在一个顶级基类子对象来解决问题。没有它,每个父类middle1&amp; middle2拥有自己的base类副本,因此导致含糊不清。

  

即使我们没有多重继承,我们是否可以始终将公共虚拟写入安全性。

如果没有多重继承,则没有理由使用virtual继承。多重继承是存在虚拟继承概念的目的。

答案 2 :(得分:1)

虚拟基类实现了额外的间接级别,以解决钻石问题(参见this question)。

如果您始终使用虚拟继承,则始终会受到额外间接级别导致的性能损失。

因此,我建议您在必要时仅使用虚拟继承。