协方差和隐藏在C ++中

时间:2013-02-22 12:40:08

标签: c++ covariance

有人可以解释每行输入背后的原因吗?

Class A {
bool f(A* a) { return true; }
}
class B : public A {
bool f(B* b) { return false; }
}
void f() {
A* a = new A();
A* ab = new B();
B* b = new B();
a->f(a); a->f(ab); a->f(b); // true, true, true
ab->f(a); ab->f(ab); ab->f(b); // true, true, true
b->f(a); b->f(ab); b->f(b); // error, error, false
}

1 个答案:

答案 0 :(得分:1)

B有两个名称相同的非虚拟方法:bool f(A*)bool f(B*)

通常,这些都是超载;但是由于一个是从基类继承而来的,所以它被后者隐藏了。它仍然可以访问,只需要一些特殊的语法来调用它,例如:

B b;
B* param;
b.f(param);    // calls B::f(B*)
b.B::f(param); // same
b.A::f(param); // calls the hidden A::f(A*)

所以:

a->f(a); a->f(ab); a->f(b);

这个很简单:a属于A*类型,因此将调用A::f(A*),类型B*的参数将转换为A*

ab->f(a); ab->f(ab); ab->f(b);

同样的事情发生,因为ab也是A*类型。

b->f(a); b->f(ab);

由于b类型为B*b->f只能引用B::f(B*)(隐藏A::f),因此无效。您无法隐式地从A*转换为B*

您可以明确地提及隐藏方法:

  

B->一种:: F(一); B->一种::的F(ab);

最后一部作品,只需拨打B::f(B*)

b->f(b);

Sample at ideone


说明:

这里的功能是否为虚拟并不重要。它们具有不同的参数类型,因此不能覆盖另一个。一个人只能隐藏另一个。

C ++允许协变返回类型(如果args匹配,您可能希望virtual A* foo()中的Avirtual B* foo()中的B。{}但是,C ++不允许使用协变或逆变参数类型。