抽象中产阶级的虚拟继承

Virtual inheritance with abstract middle class

本文关键字:继承 虚拟 中产阶级 抽象      更新时间:2023-10-16

这不是一个关于如何做某事的问题,我对虚拟继承很了解,我知道一些绕过这个问题的方法,但没有一种是我满意的。

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

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默认构造函数,它使用一些垃圾值来构造它的引用。然后在该构造函数中使用assert(),这样我就知道它永远不会被调用。。。当然,这导致我不得不对所有应该是编译时错误的东西进行运行时检查,而且它实际上还要求存在一个垃圾整数来获得的引用。

2) 我可以把引用传递给每一个抽象的中产阶级,并使用它。。。但这会导致信息的严重重复,当这些链变长时(就像它们一样),维护它是非常乏味的。此外,还必须向每个类传递一个额外的变量,这会对性能造成影响。

(如果我的问题很难理解,我很抱歉-如果有人能更好地描述我的困境,那就太棒了,我很难用语言表达出来)

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

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

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

你的第二个解决方案是正确的。如果链上的构造函数是内联的,那么根本不会影响性能。

(顺便说一句,这与虚拟继承完全无关。非虚拟继承也会遇到同样的问题。)

为什么不声明一个默认构造函数。。。

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

并将其保留为未定义-最坏的情况是,如果实际尝试使用它,则会出现链接时间错误。

请参阅ideone.com