使用多重继承时的编译错误

Compilation error when using multiple inheritance

无法编译我的程序。由于历史原因,我的应用程序中有 类 的 "complicated" 层次结构。现在我遇到了另一个问题:由于这种层次结构,它无法编译。我的项目太大,无法在此处显示,但您可以在下面看到演示该问题的示例。有没有一种简单而优雅的方法来修复它?每个 interface/class 都有非常多的方法。 提前致谢。

struct ITest
{
    virtual ~ITest() {}
    virtual void a() = 0;
    // and many other methods
};

struct Test1 : public ITest
{
    virtual ~Test1() {}
    virtual void a() override {}
    // and many other methods overrides from ITest
    // plus a lot of other logic
};

struct ExtendedTest1 : public Test1
{
    virtual ~ExtendedTest1() {}
    // a lot of some other stuff
};

struct ITest2 : public ITest
{
    virtual ~ITest2(){}
    // and big count of the its methods and logic
};

struct MainClass : public ExtendedTest1, public ITest2
{
     virtual ~MainClass(){}
     // a lot of logic
};

int main()
{
    MainClass mainClassObj;
    return 0;
}

错误:

main.cpp: In function ‘int main()’:
main.cpp:36:15: error: cannot declare variable ‘mainClassObj’ to be of abstract type ‘MainClass’
     MainClass mainClassObj;
               ^~~~~~~~~~~~
main.cpp:28:8: note:   because the following virtual functions are pure within ‘MainClass’:
 struct MainClass : public ExtendedTest1, public ITest2
        ^~~~~~~~~
main.cpp:4:18: note:    virtual void ITest::a()
     virtual void a() = 0;
                  ^

不严格判断:)

UPD:在问这个问题之前,我确实尝试过虚拟继承来解决我的问题,但它没有用。所以在建议再试一次之后,它起作用了)所以,替换这些行解决了我的问题:

struct Test1 : public ITest  --->  struct Test1 : virtual public ITest
struct ITest2 : public ITest ---> struct ITest2 : virtual public ITest

我知道,我们必须避免虚拟继承,但由于历史原因和代码量非常大,我们不能

谢谢大家的帮助!

函数 a 纯虚拟的,因为它没有在层次结构中的任何地方实现 MainClass -> ITest2 -> ITest.

更多讨论参见多重继承的“deadly diamond of death”问题。

如果您不确定自己在做什么,最简单的解决方案是避免进行此类继承。其次,您可以考虑在 MainClass 中实现 a,如果您期望的那样,它将参数转发给 Test1 中对 a 的合格调用。

MainClass 有两个基数 类,它们都(直接或间接)衍生自 ITest。所以 MainClass 中有两个 ITest 子对象。其中一个基础 类 提供了对 a 的覆盖,但另一个 (ITest2) 没有。 Test1 中的实现无法从 ITest2 访问。所以 MainClass 需要提供一个实现。

如果您希望甚至从 ITest2 子对象调用 Test1::a,您可以让 MainClass 将这些调用重定向到 Test1::a

struct MainClass: public ExtendedTest1, public ITest2
{
    // ...
    void a() override { ExtendedTest1::a(); }
};

另一种可能是virtual inheritance

你需要Virtual Inheritance.

虚拟继承可以摆脱冗余功能:

Instead, if classes B and C inherit virtually from class A, then objects of class D will contain only one set of the member variables from class A.

如果您虚拟继承,您将摆脱重复的抽象函数。