// A Simple handle class that uses sharing and supports clone().

#include <utility>
#include <string>
#include <iostream>

template < typename T >
class handle {

  public:

    handle() : tp(0), ref_cnt(new size_t(1)) { }
    handle(T * tp) : tp(tp), ref_cnt(new size_t(1)) { }
  
   ~handle(void) { 
     if (--*ref_cnt == 0) {
       delete tp; 
       delete ref_cnt;
       }
     }

    handle(const handle & th) 
      : tp(th.tp), ref_cnt(th.ref_cnt) { ref_cnt++; }

    handle & operator = (const handle & th) {
      ++*th.ref_cnt;
      if (--*refptr == 0) {
	delete refptr;
	delete p;
	}
      ref_cnt = th.ref_cnt;
      tp = th.tp;
      return *this;
      }

    void uniqify(void) {
      if (*ref_cnt != 1) {
	--*ref_cnt;
	ref_cnt = new size_t(1);
	tp = tp ? tp->clone() : 0;
	}
      }

    operator bool (void) const {
      return tp;
      }

    T & operator * (void) {
      assert(tp);
      return *tp;
      }

    T * operator -> (void) {
      assert(tp);
      return tp;
      }

  private:

    T * tp;
    size_t * ref_cnt;
  };


struct widget {
  std::string name;
  std::string type;
  widget * clone(void) { 
    widget * wp = new widget();
    wp->name = name;
    wp->type = type;
    return wp;
    }
  };


std::ostream & 
operator << (std::ostream & os, const widget & w) {
  return os << "A " << w.type 
            << " widget named " << w.name;
  }


int
main() {
  handle<widget> w1h = new widget();

  w1h->name = "joe";
  w1h->type = "blue";

  handle<widget> w2h = w1h;
  w2h.uniqify();
  w2h->type = "green";

  std::cout << "w1h:  " << *w1h << ".\n";
  std::cout << "w2h:  " << *w2h << ".\n";
  }


syntax highlighted by Code2HTML, v. 0.9