I am trying to understand virtual functions as well as virtual inheritance. For the most part, I think I successfully grasp it and its relation to polymorphism, I have been reading how the vptr works with derived objects and what not, however the example below is throwing me off, it is one I found in an Algorithms and Data Structures in C++ book:
#include <iostream>
using namespace std;
class Class1 {
public:
virtual void f() {
cout << "Function f() in Class1\n";
}
void g() {
cout << "Function g() in Class1\n";
}
};
class Class2 {
public:
virtual void f() {
cout << "Function f() in Class2\n";
}
void g() {
cout << "Function g() in Class2\n";
}
};
class Class3 {
public:
virtual void h() {
cout << "Function h() in Class3\n";
}
};
int main() {
Class1 object1, *p;
Class2 object2;
Class3 object3;
p = &object1;
p->f();
p->g();
p = (Class1*) &object2;
p->f();
p->g();
p = (Class1*) &object3;
p->f(); // possibly abnormal program termination;
p->g();
// p->h(); // h() is not a member of Class1;
return 0;
}
Output:
Function f() in Class1
Function g() in Class1
Function f() in Class2
Function g() in Class1
Function h() in Class3
Function g() in Class1
I understand everything except the last p->f();
. As a preface, I get that we cannot directly call h()
from p
because of the casting into a Class1
type, but shouldn't the Class3
vptr point only to the virtual function h()
in its vtable, and if so, then shouldn't it look for f()
in Class3's
vtable and not find it? Why does it think that Class1::f()
is Class3::h()
, its not like Class3
is inherited from Class1
...and for the record, if we rewrite Class3
to be:
class Class3 : public Class1 { // publicly inherit from Class1 is only difference
public:
virtual void h() {
cout << "Function h() in Class3\n";
}
};
and upcast into a Class1
pointer, and then call p->f()
it gives us Class1::f()
as expected, I just cannot figure out why it even lets us call p->f()
when Class3
does not inherit from Class1
.