use*_*349 7 c++ inheritance interface multiple-inheritance virtual-inheritance
我制作了如下测试代码:
#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;
}
Run Code Online (Sandbox Code Playgroud)
我编写此代码的原因是测试函数funcBase()是否可以在DDerived实例中调用.当我尝试编译此代码时,我的C++编译器(Visual Studio 2010)给了我一个编译错误消息.在我看来,这段代码没有问题,因为可以确定该函数funcBase()将在接口的某个派生类中实现(因此覆盖)DDerived,因为它是纯虚拟的.换句话说,任何类型的指针变量都Implementation *应该与派生Implentation并覆盖该函数的类的实例相关联funcBase().
我的问题是,为什么编译器会给我这样的错误信息?为什么C++语法是这样定义的; 即,将此案件视为错误?如何让代码运行?我想允许接口的多重继承.当然,如果我使用"虚拟公共"或重新声明函数funcBase()在Implementation像
interface DDerived : public Derived1, public Derived2
{
virtual void funcBase() = 0;
virtual void funcDDerived() = 0;
};
Run Code Online (Sandbox Code Playgroud)
然后一切都运行没有问题.
但我不想这样做并寻找更方便的方法,因为虚拟继承可能会降低性能,如果类的继承关系非常复杂,则重新声明是如此繁琐.除了使用虚拟继承之外,是否有任何方法可以在C++中启用接口的多重继承?
正如您所定义的那样,您的对象结构如下所示:

这里重要的一点是每个实例都Implementation包含两个完全独立的实例Base.你提供的覆盖Base::funcBase,但它不知道你是否尝试覆盖funcBase了Base你继承了通过Derived1,或者Base你继承了通过Derived2.
是的,处理这个问题的干净方法是虚拟继承.这将改变你的结构,所以只有一个Base实例:

这几乎无疑是你真正想要的.是的,它在原始编译器和25 MHz 486等时代因性能问题而闻名.使用现代编译器和处理器,您不太可能遇到问题.
另一种可能性是某种基于模板的替代方案,但这往往遍及代码的其余部分 - 也就是说Base *,您编写的模板可以与提供函数A,B和C的任何东西一起使用,而不是传递a ,然后传递(相当于)Implementation作为模板参数.
C++ 语言的设计方式是,在第一种没有虚拟继承的方法中,该方法将有两个父副本,并且无法确定要调用哪一个。
虚拟继承是从多个基继承相同函数的 C++ 解决方案,因此我建议仅使用该方法。
或者,您是否考虑过不从多个基础继承相同的功能?您是否真的有一个派生类,您需要能够根据上下文将其视为Derived1or Derived2OR ?Base
在这种情况下,详细说明具体问题而不是人为的示例可能有助于提供更好的设计。