#include<iostream>
using std::cout;
using std::endl;

struct Widget {
  void pre() {cout<<"pre"<<endl;};
  void post() {cout<<"post"<<endl;};

  void f1() {cout<<"f1"<<endl;}
  void f2() {cout<<"f2"<<endl;}
  void f3() {cout<<"f3"<<endl;}
  void f4() {cout<<"f4"<<endl;}

};


template<typename T> struct Wrapper {
  T* _p;
  Wrapper(T* p):_p(p) {_p->pre();}
  ~Wrapper()          {_p->post();}

  T*  operator->() {return _p;}

}; 



template<typename T> struct Smart_ptr {
  T *_p;
  Smart_ptr(T *p):_p(p) {};
  ~Smart_ptr(){delete _p;};

  Wrapper<T> operator->()   {return Wrapper<T>(_p);};
};


main() {

  Smart_ptr<Widget> pw(new Widget);

  pw->f1();

  pw->f2();


}