#include <iostream>

class Hoge{
   Hoge(){std::cout<<"new"<<std::endl;}
   Hoge(Hoge const &);
   Hoge& operator=(Hoge const &);
   ~Hoge(){std::cout<<"del"<<std::endl;}
public:
   static Hoge* Create(){return new Hoge();}
   static void Delete(Hoge* p){delete p;}
   void f(){std::cout<<"f"<<std::endl;}
   void f()const{std::cout<<"f const"<<std::endl;}
};

class HogePtr{
   Hoge* p;
   HogePtr(const HogePtr&);
   HogePtr& operator=(const HogePtr&);
public:
   HogePtr(Hoge* ap):p(ap){}
   ~HogePtr(){Hoge::Delete(p);}
   Hoge& operator*(){return *p;}
   const Hoge& operator*() const {return *p;}
   Hoge* operator->(){return p;}
   const Hoge* operator->() const{return p;}
};

int main(){
  HogePtr p(Hoge::Create());
  p->f();

  const HogePtr p2(Hoge::Create());
  p2->f();

  return 0;
}