0

Consider the following code:

#include <cstdio>

struct Base {
  void callNormalFn() {
    normalFn();
  }
  void callVirtualFn() {
     virtualFn();
  }
  void normalFn() {
    printf("Base::normalFn\n");
  }
  virtual void virtualFn() {
    printf("Base::virtualFn\n");
  }
};

struct Derived : Base {
  void callNormalFn() {
    Base::callNormalFn();
  }
  void callVirtualFn() {
    Base::callVirtualFn();
  }
  void normalFn() {
    printf("Derived::normalFn\n");
  }
  virtual void virtualFn() {
    printf("Derived::virtualFn\n");
  }
};

int main() {
  Derived d = {};
  d.callVirtualFn();
  //=> Derived::virtualFn (why?)
  d.callNormalFn();
  //=> Base::normalFn (why?)
}

From c++ virtual function call without pointer or reference, my understanding says that:

  • there is an implicit this pointer inside Base::callVirtualFn() or Base::callNormalFn(), e.g. this->virtualFn()
  • the this pointer should point to the current object being operated on (in this case, the Derived class)

Why is then the this pointer resolves to different classes when calling normal vs virtual functions?

  • 1
    `virtual` functions are usually looked-up from a `vtable`, which is a table of member function pointers. So, even if you have a pointer or reference of base class type, it's `vtable` is that of the most derived class. – Ted Lyngmo Feb 13 '22 at 11:46
  • 1
    The details of virtual method management techniques are not part of the language standard; only the *behavior* is defined and mandated. Commonly, vendors use some implementation of a *virtual method table* (a.k.a a `vtable`), where the polymorphic overrides of derivations are managed. The base members are still available via namespace resolution if desired. (e..g `Base::virtualFn` can be invoked from either `Base` or `Derived` members directly, and, depending on permissions, even instances (`d.Base::virtualFn();`). – WhozCraig Feb 13 '22 at 11:53
  • Here's an article describing how it could look like: [Demystifying Virtual Tables In C++ – Part 3 Virtual Tables](https://www.martinkysel.com/demystifying-virtual-tables-in-c-part-3-virtual-tables/). SO Q&A:s: [Virtual Table layout in memory?](https://stackoverflow.com/questions/1342126/virtual-table-layout-in-memory) and [C++ virtual table layout of MI(multiple inheritance)](https://stackoverflow.com/questions/15921372/c-virtual-table-layout-of-mimultiple-inheritance) – Ted Lyngmo Feb 13 '22 at 11:55
  • Did you expect the same behaviour? Why? – MatG Feb 13 '22 at 12:12
  • `this` always resolves to the type of the class the method is implemented on. What `virtual` does is change how the method is looked up. You should get a C++ textbook; it will explain in more detail. – Raymond Chen Feb 14 '22 at 14:31

0 Answers0