I am a bit confused about multi-level inheritance and virtual functions in C++. In the example below, I have 3 levels with Bottom
inheriting from Middle
inheriting from Top
.
If I declare the function in Top
as virtual
and use a pointer of type Middle
, it still overrides the function declared in Middle
even though it's not declared virtual
.
I was expecting:
Middle* ptr = new Bottom();
ptr->hello(); // Expectation: "Hello Middle" (Actual: "Hello Bottom")
and
Top* ptr = new Bottom();
ptr->hello(); // "Hello Bottom"
But that doesn't seem to be the case. Why is this?
Full code:
#include <iostream>
// Top
// ^
// Middle
// ^
// Bottom
struct Top {
// This is set to virtual.
virtual void hello() { std::cout << "Hello Top\n"; }
};
struct Middle : public Top {
// But not this.
void hello() { std::cout << "Hello Middle\n"; }
};
struct Bottom : public Middle {
// So why is this called if the type is Middle?
void hello() { std::cout << "Hello Bottom\n"; }
};
int main() {
Middle *ptr = new Bottom(); // Will use hello() in Bottom.
// Top *ptr = new Bottom(); // Same result as the above.
ptr->hello();
delete ptr;
return 0;
}
Derived functions are virtual no matter you specify them virtual or not if the base function was virtual:
If some member function vf is declared as virtual in a class Base, and some class Derived, which is derived, directly or indirectly, from Base, has a declaration for member function with the same
name parameter type list (but not the return type) cv-qualifiers ref-qualifiers Then this function in the class Derived is also virtual (whether or not the keyword virtual is used in its declaration) and overrides Base::vf (whether or not the word override is used in its declaration).
If you wanted to access the base functions you can use:
ptr->Top::hello();
Middle* ptr2 = new Bottom();
ptr2->Middle::hello();
delete ptr;
delete ptr2;
Live on godbolt
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With