If an overridden C++ function calls the parent function, which calls another virtual function, what is called?
I'm learning about polymorphism, and I am confused by this situation: Let's say I have the following C++ classes:
class A{
开发者_StackOverflow中文版 ...
virtual void Foo(){
Boo();
}
virtual void Boo(){...}
}
class B : public A{
...
void Foo(){
A::Foo();
}
void Boo(){...}
}
I create an instance of B and call its Foo() function. When that function calls A::Foo(), will the Boo() method used be that of class A or B? Thanks!
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 .
Since Boo()
is virtual, the derived class' override is called.
Boo();
is just a short-hand for this->Boo();
, where you can see that a virtual function is called through a pointer. (this
is of type A* const
within Foo()
.) And virtual functions called through a reference or a pointer will always call the override in the most-derived class (except when called from a constructor or destructor).
Inside A,
virtual void Foo(){
Boo();
}
gets translated to this->Boo()
;since Boo is declared virtual in A, the derived class's method Boo gets called. Try not declaring Boo as virtual in A just for experimentation -- you'd see that A->Boo() is getting called.
Arpan
精彩评论