假设有这个接口:
class A{
public:
virtual foo()=0;
};
以及实现此接口的类B
:
class B:public A{
public:
virtual foo(){} //Foo implemented by B
}
最后,C
类A
类并B
为基类:
Class C : public A, public B {
};
我的问题是,有一种方法可以告诉编译器foo
的实现是类B
的实现,而无需显式调用B::foo()
?
正如@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;
}
当然,正如其他答案所指出的那样,问题中的代码本身根本不需要这样做。
只需使用虚拟继承,这样B
提供的A
子对象与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);
将传递给虚函数的A*
不是实现所需的B*
。 如果B
继承自A
,则编译器将生成B::foo
以接受A* const subobject
并从该子对象指针中查找B* const this
对象。 但B::foo
对C
的关系一无所知。
由于您的示例中有两个基类(这可能是设计问题/设计气味,我会对此进行审查),因此您必须显式调用您所追求的实现,无论是A::foo()
还是B:foo()
。
如果 B 所做的只是提供foo()
的实现,我会考虑将实现移动到 A 中(你可以为纯虚函数提供实现),但即使在这种情况下,你也必须通过其限定名称调用它。