为了账号安全,请及时绑定邮箱和手机立即绑定

在C+中,什么是虚拟基类?

在C+中,什么是虚拟基类?

C++
慕尼黑的夜晚无繁华 2019-06-15 17:24:57
在C+中,什么是虚拟基类?我想知道什么是“虚拟基类“是什么意思?让我举一个例子:class Foo{public:     void DoSomething() { /* ... */ }};class Bar : public virtual Foo{public:     void DoSpecific() { /* ... */ }};

3 回答

?
墨色风雨

TA贡献1853条经验 获得超6个赞

关于内存布局

另外,可怕的钻石的问题是基类多次出现。因此,对于常规继承,你认为你拥有:

  A / \
B   C
 \ /
  D

但是在内存布局中,您有:

A   A|   |B   C
 \ /
  D

这就解释了为什么打电话的时候D::foo(),你有一个模糊的问题。但真品的成员变量时出现问题。A..例如,假设我们有:

class A{
    public :
       foo() ;
       int m_iValue ;} ;

当你尝试访问m_iValue从…D,编译器会提出抗议,因为在层次结构中,它会看到两个m_iValue一个也没有。如果你修改一个,比如说,B::m_iValue(那是A::m_iValue父母B), C::m_iValue不会被修改(即A::m_iValue父母C).

这是虚拟继承带来方便的地方,就像它一样,您将回到真正的菱形布局,而不仅仅是一个foo()方法,但也只有一个和唯一一个。m_iValue.

什么会出错?

想象一下:

  • A

    有一些基本特征。
  • B

    添加某种酷的数据数组(例如)
  • C

    添加一些很酷的特性,比如观察者模式(例如,

    m_iValue).

  • D

    继承自

    B

    C

    ,因此

    A.

具有正常继承,修改m_iValue从…D是模棱两可的,这必须解决。即使是这样,也有两个m_iValuesD,所以你最好记住这一点,同时更新这两者。

使用虚拟继承,修改m_iValue从…D没事的.。但是.。假设你D..通过它C接口,你附加了一个观察者。并通过它B接口,您可以更新酷数组,这会产生直接更改的副作用。m_iValue...

随着…的变化m_iValue直接完成(不使用虚拟访问器方法),观察者通过C不会被调用,因为实现侦听的代码在C,和B不知道这件事.。

结语

如果你有一个钻石在你的等级,这意味着你有95%的事情做错了上述等级。


查看完整回答
反对 回复 2019-06-15

添加回答

代码语言

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信