Unless you qualify a function call with the class, all method calls will be treated equal, that is dynamic dispatch if virtual, static dispatch if not virtual. When you fully qualify with the class name the method you are calling you are effectively disabling the dynamic dispatch mechanism and introducing a direct method call.
class A{
virtual void Foo(){
Boo(); // will call the final overrider
A::Boo(); // will call A::Boo, regardless of the dynamic type
}
virtual void Boo();
};
class B : public A{
void Foo(){
//Foo(); // Would call the final overrider
// (in this case B: infinite recursion)
A::Foo(); // Will call A::Foo, even if the object is B
}
void Boo();
};
The implicit this
pointer is not an important part of the discussion here, as exactly the same happens when the call is made with an explicit object:
B b;
b.Foo(); // will call B::Foo -- note 1
b.A::Foo(); // will call A::Foo
Note 1: in this example, the compiler can elide the dynamic dispatch mechanism as it knows the concrete type of the instance (it sees the definition and it is not a reference/pointer) but you can imagine the same would happen if b
was a reference, or equivalently if it was a pointer with ->
instead of .