C ++如何从具有不同返回类型的接口多重继承?
Posted
技术标签:
【中文标题】C ++如何从具有不同返回类型的接口多重继承?【英文标题】:C++ How to multiple inherits from interfaces with different return types? 【发布时间】:2012-11-19 22:00:31 【问题描述】:也许我有两个函数名称和参数相同但返回值不同的接口:
struct A virtual void foo() = 0; ;
struct B virtual int foo() = 0; ;
如何定义继承此接口的类 C(如果可能的话)? 例如我写了一些没有编译的伪代码:
// this code is fake, it doesn't compiled!!
struct C : A, B
// how to tell compiler what method using if referenced from C?
using void foo(); // incorrect in VS 2012
// and override A::foo() and B::foo()?
virtual void foo() std::cout << "void C::foo();\n"; // incorrect
virtual int foo() std::cout << "int C::foo();\n"; return 0; // incorrect
// ... for use in code
C c;
A &a = c;
B &b = c;
c.foo(); // call void C::foo() when reference from C instance
a.foo(); // call void C::foo() when reference from A instance
b.foo(); // call int C::foo() when reference from B instance
【问题讨论】:
你为什么想要这样的东西? 也许他不拥有A和B;但必须使 C 实现两者。似乎是一个合理的问题 这在 C++ 中是不可能的(不是你编写的那样)。函数由它们的参数类型而不是它们的返回类型来标识。 仅供参考 - C# 让你说 A:foo , B:foo 在这种情况下(显式实现) ***.com/questions/2004820/… 【参考方案1】:这是不可能的,但不是因为多重继承。由于类C
中foo
的无效重载而产生歧义。您不能同时拥有int foo()
和void foo()
,因为返回类型不是函数签名的一部分,因此编译器将无法解析对foo
的调用。您可以将您的接口视为A
和B
类的联合,因此从逻辑上讲,问题在实际继承之前就已经存在。由于从编译器的角度来看 A
和 B
是 2 个不同且不相关的类型,因此在编译它们时没有问题,并且错误会延迟到类 C
中的实际统一点。
在此处查看有关函数签名和重载的更多信息:Is the return type part of the function signature?
【讨论】:
【参考方案2】:您可以明确限定。
class C : A, B
public:
void A::foo() ...
int B::foo() ...
;
编辑:
这似乎是一个 MSVC 扩展,而不是标准。
【讨论】:
我也是这么认为的,但是尝试编译它对我来说失败了。我还没有找到正确的语法,但是... 我找到了原因。我认为这是一个 MSVC 扩展。标准没有涵盖这种情况似乎很奇怪(而且更奇怪的是,MSVC 扩展实际上会修补一个漏洞而不是造成几个 :P)。 好东西。除了通过C
类的实例进行强制转换之外还有什么方法可以调用它们?【参考方案3】:
您可以做的是将所有共享内容放入virtual
基类中,例如C_base
,并覆盖辅助类中相互冲突的virtual
函数。由于C
的共享内容在C_base
中很容易获得,因此基本上就像在最派生的C
中一样。最后,你C
班级只是因为班级把事情拉到一起:
struct A virtual void foo() = 0; ;
struct B virtual int foo() = 0; ;
struct C_base int all_data; ;
struct A_aux: virtual C_base, A
void foo() std::cout << "A_aux::foo()\n";
;
struct B_aux: virtual C_base, B
int foo() std::cout << "B_aux::foo()\n"; return 0;
;
struct C : A_aux, B_aux
using A_aux::foo;
;
【讨论】:
【参考方案4】:不可能使用相同的签名覆盖虚函数的返回类型(正如@icepack 的回答所解释的那样)。
另一种方法可能是让模板基类声明foo()
,并将返回类型指定为模板参数,并为具体的返回参数类型提供特化。
这将是对@Dietmar Kühl 提议的概括。
【讨论】:
以上是关于C ++如何从具有不同返回类型的接口多重继承?的主要内容,如果未能解决你的问题,请参考以下文章