-4

誰かが各行の入力の背後にある理由を説明できますか?

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
}
4

1 に答える 1

1

B同じ名前の2つの非仮想メソッドがあります:bool f(A*)bool f(B*)

通常、これらは過負荷になります。しかし、1つは基本クラスから継承されているため、基本クラスによって隠されています。それはまだアクセス可能です、それを呼び出すためにいくつかの特別な構文が必要です、例えば:

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::fA*からを暗黙的に変換することはできませんB*

ただし、非表示のメソッドについては明示的に言及できます。

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

そして最後の作品は、単に呼び出すだけですB::f(B*)

b->f(b);

ideoneでのサンプル


備考:

ここでは、関数が仮想であるかどうかは関係ありません。それらは異なる引数タイプを持っているので、一方が他方をオーバーライドすることはできません。一方は他方を隠すことしかできません。

C ++では、共変の戻り型を使用できます(引数が一致する場合は、virtual A* foo()inAvirtual B* foo()inが必要になる場合があります)。Bただし、 C++では共変または反変の引数型は許可されていません。

于 2013-02-22T12:57:31.557 に答える