C语言中多接口继承的歧义

我制作了如下测试代码:

#include <iostream>
using namespace std;

#ifndef interface
#define interface struct
#endif

interface Base
{
    virtual void funcBase() = 0;
};

interface Derived1 : public Base
{
    virtual void funcDerived1() = 0;
};

interface Derived2 : public Base
{
    virtual void funcDerived2() = 0;
};

interface DDerived : public Derived1, public Derived2
{
    virtual void funcDDerived() = 0;
};

class Implementation : public DDerived
{
public:
    void funcBase() { cout << "base" << endl; }
    void funcDerived1() { cout << "derived1" << endl; }
    void funcDerived2() { cout << "derived2" << endl; }
    void funcDDerived() { cout << "dderived" << endl; }
};

int main()
{
    DDerived *pObject = new Implementation;
    pObject->funcBase();

    return 0;
}

我编写此代码的原因是测试函数funcBase()是否可以在DDerived实例中调用.当我尝试编译此代码时,我的C编译器(Visual Studio 2010)给了我一个编译错误消息.在我看来,这段代码没有问题,因为可以确定函数funcBase()将在接口DDerived的某个派生类中实现(因此覆盖),因为它是纯虚拟的.换句话说,任何类型为Implementation *的指针变量都应该与派生Implentation并覆盖函数funcBase()的类的实例相关联.

我的问题是,为什么编译器会给我这样的错误信息?为什么C语法是这样定义的;即,将此案视为错误?如何让代码运行?我想允许接口的多重继承.当然,如果我使用“虚拟公共”或者在实现中重新声明函数funcBase()

interface DDerived : public Derived1, public Derived2
{
    virtual void funcBase() = 0;
    virtual void funcDDerived() = 0;
};

然后一切都运行没有问题.

但我不想这样做并寻找更方便的方法,因为虚拟继承可能会降低性能,如果类的继承关系非常复杂,则重新声明是如此繁琐.除了使用虚拟继承之外,是否有任何方法可以在C中启用接口的多重继承?

正如您所定义的那样,您的对象结构如下所示:

这里重要的一点是,每个实现实例都包含两个完全独立的Base实例.您提供了Base :: funcBase的覆盖,但它不知道您是否尝试覆盖通过Derived1继承的Base的funcBase,或者您通过Derived2继承的Base.

是的,处理这个问题的干净方法是虚拟继承.这将改变你的结构,所以只有一个Base实例:

这几乎无疑是你真正想要的.是的,它在原始编译器和25 MHz 486等时代因性能问题而闻名.使用现代编译器和处理器,您不太可能遇到问题.

另一种可能性是某种基于模板的替代方案,但这往往遍及代码的其余部分 – 即,不是传递Base *,而是编写一个模板,该模板将与提供函数A,B和C,然后传递(相当于)Implementation作为模板参数.

相关文章
相关标签/搜索