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

问题描述 投票:0回答:3

无法编译我的程序。由于历史原因,我的应用程序中的类有点“复杂”的层次结构。现在,我面临另一个问题:由于这种层次结构,它无法编译。我的项目太大,无法在此处显示,但是在下面您可以看到演示问题的示例。有没有简单而优雅的方法来修复它?每个接口/类都有很多方法。预先感谢。

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

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

感谢大家的帮助!

c++ inheritance compiler-errors multiple-inheritance
3个回答
1
投票

您需要Virtual Inheritance

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

相反,如果类B和C实际上从类A继承,则类D的对象将仅包含一组来自类A的成员变量。

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


2
投票

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

更多信息请参见多继承的“ deadly diamond of death”问题。

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


2
投票

MainClass有两个基类,这两个基类都是(直接或间接)从ITest派生的。因此,ITest中有两个MainClass子对象。这些基类之一提供a的替代,但另一个(ITest2)不提供。无法从Test1访问ITest2中的实现。因此,MainClass将需要提供一个实现。

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

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

另一种可能性是virtual inheritance

© www.soinside.com 2019 - 2024. All rights reserved.