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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用多重继承时的编译错误相关的知识,希望对你有一定的参考价值。

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

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

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

感谢大家的帮助!

答案

您需要Virtual Inheritance

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

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

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

另一答案

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

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

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

另一答案

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

以上是关于使用多重继承时的编译错误的主要内容,如果未能解决你的问题,请参考以下文章

继承 PortableServer::RefCountServantBase 时的编译错误

QObject的多重继承

使用 MatLab dll 时出现 C++ 错误:找到一个或多个多重定义符号

使用 ARM GCC 编译列表迭代器时的模板编译时错误

在 iOS 下使用 Stitcher 时的 OpenCV 编译器错误

C语言编译时的错误