#include <vector>
#include <iostream>

using std::cout;
using std::endl;

struct Base
{
  void one() {
    cout << "Base: one" << endl;
  }

  void two() {
    cout << "Base: two" << endl;
  }

  virtual void three() {
    cout << "Base: three" << endl;
  }

  virtual void four() {
    cout << "Base: four" << endl;
  }
};

struct Derived : public Base {
  void two() {
    cout << "Derived: two" << endl;
  }

  void three() { // implicitly virtual
    cout << "Derived: three" << endl;
  }
};

int main()
{
  Base *xx = new Base();
  Derived *yy = new Derived();
  Base *zz = yy;

  /**
   * In gdb, try the following commands:
   * break 43
   * run
   *
   * p *xx
   * p *yy
   * p *zz
   *
   * info vtbl xx
   * info vtbl yy
   * info vtbl zz
   *
   * x/4xg xx
   * x/4xg *(void**)xx
   * p **(void***)xx
   * p **(void***)xx@2
   *
   * etc.
   */


  xx->one();
  yy->one();
  zz->one();

  cout << endl;

  xx->two();
  yy->two();
  zz->two();

  cout << endl;

  xx->three();
  yy->three();
  zz->three();

  cout << endl;

  xx->four();
  yy->four();
  zz->four();

  return 0;
}