Search code examples
c++callvirtual

Will a method be called virtually even if no sub-class overrides it?


Imagine you have the following classes:

class A {
  public:
    virtual void print()           { printf("A\n"); }
};
class B : public A {
  public:
    virtual void print() override  { printf("B\n"); }
};
class C : public B {
    // no override of print
};

And now if you create an instance of B and call print:

B * b = new B;
b->print();

Will this method be called virtually? In other words, will the exact method to be called determined at compile-time or run-time?

Theoretically it can be determined at compile-time, because we know, that none of sub-classes of B overrides that method, so no matter what I assign into pointer to B B * b = new C; b->print();, it will always call B::print().

Does the compiler know it too and save me from unnecessary overhead of the virtual call?


Solution

  • Theoretically it can be determined at compile-time, because we know, that none of sub-classes of B overrides that method

    You cannot determine this at compile time in general case, because C++ compiler deals with one translation unit at a time. A class from a different translation unit, say, class D : public B could override the method. However, the compiler may have no visibility into the translation unit of class D at the time the call to b->print() is translated, so the compiler must assume a virtual call.

    In order to address this shortcoming C++11 introduced final keyword, which lets programmers tell the compiler that there would be no further overrides down from this level of inheritance hierarchy. Now the compiler can optimize out the virtual call, and also enforce the requirement of no further overrides.