while trying to analyse in greater depth inheritance mechanism of C++ I stumbled upon the following example:
#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();
}
It is clear that calling
b->f()
is ambiguous, so there is no unique method f() on object Bottom. Now, calling
b->g()
works fine and prints
Base.f
Well, as far as I see this:
- static type is Bottom, so we call its
g()method, as it is non-virtual g()method is inherited from Left, so we call this inherited method- Now,
g()in Left tries to call virtual methodf(). According to C++ sepcification, we callf()method of a dynamic type of our pointer (which is Bottom)
BUT Bottom does not have method f()… at least not a unique one. Why does this program executes Left::Base::f() rather than Right::Base::f() or why does it simply not states that call to f() is ambiguous from Bottom?
The short answer is that (as you noted),
Bottomdoes not have methodf(), so there is no need in trying to call it.Bottomcontains the two subobjectsLeftandRight. Each of them inherits fromBase, soBottomcontains the member functionsLeft::f()andRight::f(), but noBottom::f(). Since Bottom does not overrideLeft::f()(usingRight::f()for example),Base::f()is the unique final overrider inLeft::g().cf. the example in 10.3.9 from the C++03 standard.