5

假设有这个接口:

class A{  
 public:  
  virtual foo()=0;  
};

还有一个B实现这个接口的类:

class B:public A{    
 public:   
  virtual foo(){} //Foo implemented by B   
}

最后,一个C具有类AB基类的类:

Class C : public A, public B {
};

我的问题是,有一种方法可以告诉编译器的实现foo是来自类的实现,B而无需显式调用B::foo()?

4

3 回答 3

3

正如@BenVoigt 在评论中指出的那样,以下答案仅由于 g++ 中的错误而有效(这意味着它不能保证继续工作,而且它绝对不可移植)。因此,尽管如果您使用特定的(有缺陷的)编译器,它可能会做您想做的事,但它不是您应该使用的选项。

一定要使用虚拟继承


这不完全是问题中的代码所暗示的场景,而是句子

我的问题是,有一种方法可以告诉编译器 foo 的实现是来自 B 类的实现,而无需显式调用 B::foo()?

似乎要求语法来区分函数的多个基本版本而不使用::限定符。

您可以使用using指令执行此操作:

#include <iostream>
class A {
public:
A(){}
virtual void foo(){std::cout<<"A func";}
};

class B: virtual public A {
  public:
  B(){}
  virtual void foo(){std::cout<<"B func";}
};
class C:virtual public A, virtual public B {
    public:
    C(){}
    using A::foo; // tells the compiler which version to use
                   // could also say using B::foo, though this is unnecessary
};

int main() {
    C c;
    c.foo(); // prints "A func"
    return 0;
}

当然,正如其他答案所指出的那样,问题中的代码本身根本不需要这样做。

于 2012-12-26T18:20:25.593 回答
2

只需使用虚拟继承,以便A提供的子B对象与C.

或者写class C : public B...无论如何,它都可以A通过基类隐式使用B


在编辑问题之前:

B::foo不兼容A::foo

所需的签名是

ReturnType /* missing from question */ foo(A* const this /* this parameter is implicit */);

但是B::foo有签名

ReturnType foo(B* const this);

将传递给虚函数的 AnA*不是B*实现所需的 a 。如果B继承自A,则编译器将生成B::foo以接受并从该子对象指针中A* const subobject查找对象。B* const thisB::foo对中的关系一无所知C

于 2012-12-26T18:07:29.247 回答
0

由于您的示例中有两个基类(这可能是设计问题/设计气味,我会回顾一下),您必须明确调用您所追求的实现,无论是它A::foo()还是B:foo().

如果 B 所做的只是提供的实现,foo()我会考虑将实现移到 A 中(您可以为纯虚函数提供实现),但即使在这种情况下,您也必须通过其限定名称来调用它。

于 2012-12-26T17:58:54.630 回答