vtable – a way to realise polymorphism (C++)

Currently most C++ compilers use vtables to realise polymorphism.

#include <iostream>

struct Base
{
  virtual void method() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};

struct Child : public Base
{
  virtual void method() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};

struct GrandChild : public Child
{
  virtual void method() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};

int main()
{
  Base* obj = new GrandChild;
  obj->method();
  delete obj;
  return 0;
}
$ g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609
$ g++ main.cpp -g

$ gdb a.out 
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
(gdb) b 22
Breakpoint 1 at 0x4009eb: file main.cpp, line 22.
(gdb) r
virtual void GrandChild::method()

Breakpoint 1, main () at main.cpp:22
22	  delete obj;

(gdb) p &obj
$1 = (Base **) 0x7fffffffdcf8
(gdb) p obj
$2 = (Base *) 0x614c20
(gdb) p *obj
$3 = {_vptr.Base = 0x400bf8 <vtable for GrandChild+16>}
(gdb) p sizeof(obj)
$4 = 8
(gdb) x/2x obj
x614c20:	0x00400bf8	0x00000000
(gdb) info symbol 0x400bf8
vtable for GrandChild + 16 in section .rodata of /<path_to_binary>/a.out
(gdb) x/2x 0x00400bf8
0x400bf8 <_ZTV10GrandChild+16>:	0x00400aae	0x00000000
(gdb) info symbol 0x00400aae
GrandChild::method() in section .text of /<path_to_binary>/a.out

(gdb) info vtbl obj
vtable for 'Base' @ 0x400bf8 (subobject @ 0x614c20):
[0]: 0x400aae <GrandChild::method()>

The object (obj @ 0x614c20) contains a pointer to the vtable (@ 0x400bf8) of its class. The vtable contains the pointers to the actual methods (GrandChild::method() @ 0x400aae).

Stack
    Addr: 0x7fffffffdcf8 | Val: 0x614c20 (objPtr)
                                    |
               /--------------------/
Heap           ↓
    Addr: 0x614c20       | Val: 0x400bf8 (obj)
                                    |
               /--------------------/
Data           ↓
    Addr: 0x400bf8       | Val: 0x400aae (vtable of GrandChild)
                                    |
               /--------------------/
Text           ↓
    Addr: 0x400aae     | Val: <asm code> (GrandChild::method())