#include <iostream>
#include <memory>

struct base {};

struct derived : base { ~derived() { std::cout << "derived::~derived\n" ; } };

int main()
{
    {
        std::shared_ptr<base> p1( new derived ) ;
        std::shared_ptr<derived> p2( new derived ) ;
        std::shared_ptr<base> p3 = p2 ;
        std::shared_ptr<base> p4 = std::make_shared<derived>() ;
    }
    std::cout << "the three derived class objects should have been destroyed by now\n" ;

    {
        std::cout << "without a virtual destructor for base, there is trouble here\n" ;
        std::shared_ptr<base> p( static_cast<base*>( new derived ) ) ;
    }
    std::cout << "the wrong destructor would have been called for the derived class object\n" ;
}
