虚拟继承与抽象中产阶级

时间:2014-11-05 05:44:05

标签: c++ inheritance abstract-class virtual-inheritance

这不是一个关于如何做某事的问题,我对虚拟继承非常熟悉,而且我知道有几种方法可以解决这个问题 - 但我没有其他任何方法可以解释。

以下是一些无法编译的代码:

struct BottomClass
{
    BottomClass(int& ref) : ref(ref) {}
    int& ref;
};

struct MiddleClassA : virtual public BottomClass
{
    MiddleClassA() /*: BottomClass()*/ {}
    virtual ~MiddleClassA() = 0;
};

MiddleClassA::~MiddleClassA(){}

struct MiddleClassB : virtual public BottomClass
{
    MiddleClassB() /*: BottomClass()*/ {}
    virtual ~MiddleClassB() = 0;
};

MiddleClassB::~MiddleClassB(){}

struct TopClass final : public MiddleClassA, public MiddleClassB
{
    TopClass(int& ref) : BottomClass(ref) {}
};

void main()
{
    int someInt;
    TopClass variable(someInt);
}

困扰我的是为什么这不能编译。我知道BottomClass没有默认构造函数,因此MiddleClassX格式不正确。但MiddleClassX是抽象类!即使我在那里指定了一个构造函数,它也不会在任何情况下使用......那么我为什么要指定它?

我甚至无法在那里提供合理的构造函数,因为MiddleClassX没有任何合理的值可以提供给BottomClass。

我的问题是:这个问题有一个优雅的解决方案吗?


我自己有一些解决方案,但我不喜欢其中任何一种解决方案:

1)我可以创建一个BottomClass默认构造函数,它使用一些垃圾值来构造它的ref。然后在该构造函数中断言()所以我知道它永远不会被调用...当然这导致我必须对应该是编译时错误的所有内容进行运行时检查,并且它实际上也要求存在一个垃圾整数来获取引用。

2)我可以将引用传递给每个抽象的中间类并使用它......但是这会导致严重的信息重复,并且当这些链变长时(就像它们那样),维持它是非常繁琐的。还必须将额外的变量传递给每个类。

(如果我的问题难以理解,我表示道歉 - 如果有人能够更好地描述我的困境,那将是非常棒的,我很难将其置于文字中)

2 个答案:

答案 0 :(得分:1)

  

即使我在那里指定了一个构造函数,它也不会在任何情况下使用

错误。抽象类的构造函数由派生类使用。毕竟抽象类仍然需要初始化,抽象类的唯一特殊之处在于你不能直接构造它们;只允许派生类构造它们,并且只作为它们自己构造的一部分。

不能派生没有构造函数的抽象类,就像任何其他没有构造函数的类都不能派生一样。

你的第二个解决方案是正确的。如果内联链上的构造函数被内联,则根本没有性能损失。

(顺便说一句,这与虚拟继承没有任何关系。你将遇到与非虚拟继承相同的问题。)

答案 1 :(得分:1)

为什么不声明默认构造函数...

BottomClass();  // deliberately undefined; use Bottom(int&)

...并保持未定义 - 最糟糕的是,如果实际尝试使用它,则会出现链接时错误。

ideone.com