mzee99
mzee99

Reputation: 191

Polymorphism with 3 classes in C++

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?

Upvotes: 3

Views: 102

Answers (2)

Shoe
Shoe

Reputation: 76240

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.

Upvotes: 10

Mercurial
Mercurial

Reputation: 2165

It happens because writing virtual keyword in subclasses is not necessary, it just improves readability.

Upvotes: 2

Related Questions