#include <iostream>

class A {
public:
  void go() { std::cout << "A::go" << std::endl; }

  virtual void calculate()  { std::cout << "A::calculate" << std::endl; }
};

class B : public A {
public:

  virtual void go() { std::cout << "B::go" << std::endl; }

  virtual void calculate()  { std::cout << "B::calculate" << std::endl; }
};

class C : public B {
public:

  void go() { std::cout << "C::go" << std::endl; }

  virtual void calculate()  { std::cout << "C::calculate" << std::endl; }
};

int main() {

  A a;
  B b;
  C c;

  std::cout << "a, b, c go" << std::endl;
  a.go();
  b.go();
  c.go();
  std::cout << std::endl;

  std::cout << "a, b, c calculate" << std::endl;
  a.calculate();
  b.calculate();
  c.calculate();
  std::cout << std::endl;

  std::cout << "A& ra = a" << std::endl;
  {
    A& ra = a;
    ra.go();
    ra.calculate();
  }
  std::cout << std::endl;

  std::cout << "A& ra = b" << std::endl;
  {
    A& ra = b;
    ra.go();
    ra.calculate();
  }
  std::cout << std::endl;

  std::cout << "A& ra = c" << std::endl;
  {
    A& ra = c;
    ra.go();
    ra.calculate();
  }
  std::cout << std::endl;

  std::cout << "B& rb = b" << std::endl;
  {
    B& rb = b;
    rb.go();
    rb.calculate();
  }
  std::cout << std::endl;

  std::cout << "B& rb = c" << std::endl;
  {
    B& rb = c;
    rb.go();
    rb.calculate();
  }
  std::cout << std::endl;

  std::cout << "C& rc = c" << std::endl;
  {
    C& rc = c;
    rc.go();
    rc.calculate();
  }
  std::cout << std::endl;
  
  return 0;
}
