#include <iostream>

struct base
{
    base() { foo() ; } // calls base::foo()
    virtual ~base() { foo() ; } // calls base::foo()

    virtual void foo() const { std::cout << "base::foo\n" ; }
    void bar() { foo() ; } // calls ???::foo
};

struct derived : base
{
    derived() { foo() ; } // calls derived::foo()
    virtual ~derived() override { foo() ; } // calls derived::foo()
    virtual void foo() const override { std::cout << "derived::foo\n" ; }
};

int main()
{
    {
        derived d ;
        // constructor of base class
        // base constructor calls foo => base::foo
        // constructor of derived class
        // derived constructor calls foo => derived::foo

        base& b = d ;
        b.bar() ;
        // calls base::bar()
        // base::bar calls foo() polymorphically => derived::foo

    } // the life-time of d is over at this point
      // destructor of derived class
      // derived destructor calls foo => derived::foo
      // destructor of base class
      // base destructor calls foo => base::foo
}
