【发布时间】:2011-01-06 11:06:19
【问题描述】:
我在 C++ 中使用伪接口,即纯抽象类。假设我有三个接口,IFoo、IBar 和 IQuux。我还有一个类 Fred 实现了这三个:
interface IFoo
{
void foo (void);
}
interface IBar
{
void bar (void);
}
interface IQuux
{
void quux (void);
}
class Fred : implements IFoo, IBar, IQuux
{
}
我想声明一个接受任何实现 IFoo 和 IBar 的对象的方法 - 例如,一个 Fred 就可以工作。我能想象到的唯一编译时方法是定义第三个接口 IFooAndBar 来实现两者,并重新声明 Fred:
interface IFooAndBar : extends IFoo, IBar
{
}
class Fred : implements IFooAndBar, IQuux
{
}
现在我可以将我的方法声明为接收 IFooAndBar*。到目前为止一切顺利。
但是,如果我还想要一个接受 IBar 和 IQuux 的不同方法会怎样?我尝试声明一个新接口 IBarAndQuux 并将 Fred 声明为继承两者:
class IFooAndBar : IFoo, IBar
{
};
class IBarAndQuux : IBar, IQuux
{
};
class Fred : IFooAndBar, IBarAndQuux
{
};
这在我将 Fred 作为 IFooAndBar 传递给方法时有效;但是,当我尝试直接调用 Fred::bar() 时,gcc 会抱怨:
error: request for member ‘bar’ is ambiguous
error: candidates are: void IBar::bar()
error: void IBar::bar()
这使这个解决方案或多或少没用。
我的下一个尝试是将 Fred 声明为从三个单独的接口继承,并让该方法接受其中一个混合接口作为参数:
class Fred : public IFoo, public IBar, public IBaz
{
};
void doTest (IBarAndBaz* pObj)
{
pObj->bar();
pObj->baz();
}
当我尝试将 Fred 作为 IBarAndBaz* 参数传递时,我得到了一个错误,正如预期的那样:
error: cannot convert ‘Fred*’ to ‘IBarAndBaz*’ for argument ‘1’ to ‘void doTest(IBarAndBaz*)’
dynamic_cast 也会产生错误(我不明白)
error: cannot dynamic_cast ‘pFred’ (of type ‘class Fred*’) to type ‘class IBarAndBaz*’ (source type is not polymorphic)
强制转换确实有效,但是:
doTest((IBarAndBaz*)pFred);
但我想知道它的安全性和便携性(我为 Linux、Mac 和 Windows 开发),以及它是否适用于实际情况。
最后,我意识到我的方法可以接受指向其中一个接口的指针和指向其他接口的 dynamic_cast 以在运行时强制执行正确的参数类型,但我更喜欢编译时解决方案。
【问题讨论】:
-
它不安全,也不便携。事实上,它在 C++ 中是未定义的。
标签: c++ inheritance interface multiple-inheritance