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

What is difference between class A:public virtual B and class A:public B

本文关键字:区别 公共 什么 虚拟      更新时间:2023-10-16
#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;
}

我知道虚拟解决了这个问题,但如何解决呢?为了安全起见,我们可以一直编写公共虚拟吗?即使我们没有多重继承。

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

如果继承是非虚拟的,则middle1基类子对象具有base基类子对象,middle2基类子对象也具有base基类子对象。因此,derive的每个实例都有两个base子对象,而调用pd->f()是不明确的——您想在base对象中的哪个对象上调用f()

使继承虚拟化意味着middle1middle2将共享derive的单个base子对象。这消除了歧义——只有一个base对象可以调用f()

我们可以一直写公共虚拟安全吗

不一定。在继承层次结构中,您可能不希望middle1middle2共享公共base子对象。你可能会争辩说,在这种情况下,你不应该编写一个从两者继承的类derive,但如果你最终遇到了这种情况,那么解决方法是:

static_cast<middle1*>(pd)->f();
pd->middle1::f();

指定要在middle1基类子对象或上调用f

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

以指定CCD_ 25。

虚拟基类实现了一个额外的间接级别,以解决钻石问题(请参阅此问题(。

如果您始终使用虚拟继承,那么您将始终承受由该附加间接级别所导致的性能损失。

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

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

virtual关键字通过使继承层次结构中只存在一个顶级基类子对象来解决这个问题。没有它,每个父类CCD_;CCD_ 28具有它们自己的CCD_。

即使我们没有多重继承,为了安全,我们是否可以一直编写公共虚拟

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