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】:

这是不可能的,但不是因为多重继承。由于类Cfoo 的无效重载而产生歧义。您不能同时拥有int foo()void foo(),因为返回类型不是函数签名的一部分,因此编译器将无法解析对foo 的调用。您可以将您的接口视为AB 类的联合,因此从逻辑上讲,问题在实际继承之前就已经存在。由于从编译器的角度来看 AB 是 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 ++如何从具有不同返回类型的接口多重继承?的主要内容,如果未能解决你的问题,请参考以下文章

使用与多重继承相关的接口的任何真实示例

如何让单个接口返回不同的数据类型?

Django:从带有元的抽象类的多重继承

如何创建具有索引签名和不同类型的固定属性的 TypeScript 接口?

类 C 语言中的返回类型多态性

Java 多重继承