私は以下を実行しようとしました:
struct B;
struct C;
struct A{
A() { f(this);}
virtual A* f(A* a) {
cout << " A::f(A)" <<endl;
return a;
}
void h() { cout << typeid(*this).name() << endl;}
void g(B* b);
};
struct B:A{
B() { f(this); }
virtual A* f(A* a) {
cout << "B::f(A)" << endl;
return a;
}
virtual B* f(B* b) {
cout << "B::f(B)" << endl;
return b;
}
virtual C* f(C* c) {
cout << "B::f(C)" << endl;
return c;
}
};
struct C: B{};
void A::g(B* b) { cout << typeid(*this).name() << endl; f(b);};
int main(){
B* b = new B();
cout << "------" << endl;
C* c = new C();
cout << "------" << endl;
c->g(b);
return 0;
}
g() は非仮想であるため、コンパイル中に選択されることに注意してください。
これを実行すると、次の出力が得られます。
A::f(A)
B::f(B)
------
A::f(A)
B::f(B)
------
1C
B::f(A) <----- Notice this
最後の行は、動的にバインドされているかのように f() を呼び出しているように見えますが、A が知っているメソッド f() にのみ呼び出していることに注意してください (これは、g() が静的にバインドされているという事実に関係していると思います)。私が期待していたのは、B::f(B) を取得することでした。
g() での f() の呼び出しがコンパイル時に計算されるのはなぜですか?