The following code prints 1 2, but I would expect it to print 1 1.
#include <iostream>
using namespace std;
class A {
public:
virtual void f() { cout << "0" << endl; }
};
class B : public A{
public:
void f() { cout << "1" << endl; }
};
class C : public B{
public:
void f() { cout << "2" << endl; }
};
int main() {
A *pa = new B();
B *pb = new C();
pa->f();
pb->f();
}
In my understanding, pa->f() executes B's f() function since A's is virtual, but why does pb->f() execute C's f() function when B's f() is not virtual.
Additionally, if I remove 'virtual' from class A, it prints 0 1, which makes sense because A and B execute their own f() functions since they aren't virtual. How come pb->f() changes if it isn't affected since it's only A that changes?
but why does pb->f() execute C's f() function when B's f() is not virtual.
Because the dynamic type of pb is C and C::f is indeed virtual. When you declare
virtual void f();
in the base class, every other void f() of the derived classes in the hierarchy is also virtual, as per §10.3/2:
If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name, parameter-type-list (8.3.5), cv-qualification, and ref- qualifier (or absence of same) as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides112 Base::vf.
(emphasis mine)
In fact:
class A {
public:
virtual void f() { cout << "0" << endl; }
};
class B : public A{
public:
virtual void f() { cout << "1" << endl; }
};
class C : public B{
public:
virtual void f() { cout << "2" << endl; }
};
is equivalent to your code. It just so happens that the C++ standard allows virtual to be omitted in those cases.
It happens because writing virtual keyword in subclasses is not necessary, it just improves readability.
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