// 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