C++ の継承メカニズムをより深く分析しようとしているときに、次の例に出くわしました。
#include<iostream>
using namespace std;
class Base {
public:
virtual void f(){
cout << "Base.f" << endl;
}
};
class Left : public Base { //NOT VIRTUAL!!!
public:
void g(){
f();
}
};
class Right : public Base{
public:
virtual void f(){
cout << "Right.f" << endl;
}
};
class Bottom : public Left, public Right{
public:
Bottom(int arg){ }
//void f() { }
};
int main(int argc,char **argv)
{
Bottom* b = new Bottom(23);
b->g();
}
呼び出していることは明らかです
b->f()
はあいまいなのでf()
、オブジェクト Bottom に固有のメソッドはありません。今、呼び出し
b->g()
正常に動作し、印刷されます
Base.f
まあ、私がこれを見る限り:
g()
静的タイプは Bottom であり、非仮想であるため、そのメソッドを呼び出しますg()
メソッドは Left から継承されているため、この継承されたメソッドを呼び出します- ここで
g()
、左で仮想メソッドを呼び出そうとしますf()
。C++ の仕様によるとf()
、ポインタの動的型 (Bottom) のメソッドを呼び出します。
BUT Bottomにはメソッドがありませんf()
...少なくとも一意のものではありません。このプログラムが実行されるのはなぜですかLeft::Base::f()
、または単に呼び出しが下からあいまいでRight::Base::f()
あると述べられないのはなぜですか?f()