虚拟基类的数据成员(Virtual base class data members)

2019-06-27 00:40发布

为什么我们建议不要在虚基类的数据成员?

什么函数成员? 如果我有共同所有的派生类任务是确定虚基类做任务还是应该从两个派生继承归类 - 从虚拟接口和滑动基础,做任务?

谢谢。

Answer 1:

作为练习,你应该只使用虚拟继承,因为它们通常与多重继承使用,以确保只有一个版本的类出现在派生类中定义的接口。 和纯接口多重继承的最安全的形式。 当然,如果你知道你在做什么,只要你喜欢,你可以使用多重继承,但它可能会导致脆弱的代码,如果你不小心。

与虚拟继承的最大缺点是,如果它们的构造函数带参数。 如果你将参数传递给一个虚基类,你强迫所有的派生类显式调用构造函数的构造函数(他们不能依赖于一个基类调用构造函数)。

我可以看到您的明确提醒的唯一原因是,在你的虚基类,这些数据可能需要构造函数的参数。

编辑我做了马丁的评论后,一些家庭的工作,感谢马林。 第一行是不完全正确的:

作为练习,你应该只使用虚拟继承,因为它们通常与多重继承使用,以确保只有一个版本的类出现在派生类中定义的接口。

虚拟继承没有什么区别,如果基类是纯接口(除了略有不同的编译器错误,在VC8,如果所有的方法都没有实现)。 它不仅使一个真正的区别,如果基类中有数据,在这种情况下,你最终用金刚石,而不是U形

Non virtual    virtual
  A     A          A
  |     |        /   \
  B     C       B     C
   \   /         \   /
     D             D

在虚拟情况下,B和C共享A的相同拷贝

但是我还是同意一切的是纯粹的接口是多重继承的最安全的形式,即使他们并不需要虚拟继承。 而事实上,构造函数的参数和虚拟继承是一种痛苦。



Answer 2:

核心建议是在虚拟底座的默认构造函数。 如果不这样做,那么每一个最派生类 (即所有子类)必须显式调用虚基类构造函数,并导致愤怒的同事敲你的办公室的门...

class VirtualBase {
public:
    explicit VirtualBase( int i ) : m_i( i ) {}
    virtual ~VirtualBase() {}

private:
    int m_i;
};

class Derived : public virtual VirtualBase {
public:
    Derived() : VirtualBase( 0 ) {} // ok, this is to be expected
};

class DerivedDerived : public Derived { // no VirtualBase visible
public:
    DerivedDerived() : Derived() {} // ok? no: error: need to explicitly
                                    // call VirtualBase::VirtualBase!!
    DerivedDerived() : VirtualBase( 0 ), Derived() {} // ok
};


Answer 3:

我从来没有见过这样的建议。

类是一组密切相关的功能和数据。 基类的目的是为具有一组共同的功能和数据可用于由派生类的重用。

我想限制自己没有在基类的数据成员和非纯虚函数会降低代码的复用,从而导致不可靠的代码从长远看量。



Answer 4:

一)成员应该是私有的 - 所以你可以在派生类中使用它们(所以你必须添加getter和setter方法,它炸毁你的界面)获得问题

B)不申报的东西,你目前不使用 - 仅在其中的类访问声明变量/使用它们

c)中虚基类应该只包含接口/虚拟方法,仅此而已

我希望帮助一点点,哪怕我的理由是不完美的,完整的:)

你好,克里斯



Answer 5:

被用来模拟在C ++接口全abtract基类不应该有数据成员-因为它们被描述的接口 ,并且实例状态是一个实现细节。

除此之外,包含虚拟函数的基类可能具有数据成员。 通常的规则,但:

  • 让他们为隐藏的可能的,如果您需要保留类不变量使用getter和setter。
    (有一个在这里的一个漏洞:如果没有与该成员相关不变,也就是说,它可以在任何给定的时间承担任何可能的值,你可以把它公开。然而,这种拒绝派生类中添加一个不变。
  • 继承设计:你的类应该定义的责任和派生类的可能性的合同,它需要的/可重写的目的是什么。


文章来源: Virtual base class data members