template <typename T> class Handle { T * tp public Handle() Handle(T *) Handle (const Handle &) Handle & operator = (const Handle &) ~Handle() operator bool() const T & operator * () const T * operator -> () const }
template <typename T> Handle<T>() : tp(0) { }
template <typename T> Handle<T>(T * tp) : tp(tp) { }
template <typename T> ~Handle<T>() if (tp) delete tp
template <typename T> ~Handle<T>() { delete tp }
tp
can't be a pointer to an array of things.
tp
is pointing?
T
does it using the clone()
function.
template <typename T> Handle<T>(const Handle & th) tp = th.tp ? th.tp->clone() : 0
template <typename T> Handle<T> & Handle<T>::operator = (const Handle & rhs) if (&rhs != this) delete tp tp = rhs.tp ? rsh.tp->clone() : 0 return *this
template <typename T> bool Handle<T>::operator bool (void) { return tp }
template <typename T> T & Handle<T>::operator * (void) const assert(tp) return *tp
template <typename T> T * Handle<T>::operator -> (void) const assert(tp) return tp
$ cat t.cc struct widget { widget(std::string str) : str(str) { std::cerr << "Creating a " << str << " widget.\n"; } ~widget() { std::cerr << "Deleting a " << str << " widget.\n"; } widget * clone(void) const { return 0; } const std::string str; }; int main() { handle<widget> w1h = new widget("red"); if (w1h) { handle<widget> w2h = new widget("blue"); } } $ g++ -o t -ansi -pedantic -Wall t.cc $ ./t Creating a red widget. Creating a blue widget. Deleting a blue widget. Deleting a red widget. $
See the complete code.
$ cat t.cc struct widget { std::string name; std::string type; widget * clone(void) const { return 0; } }; std::ostream & operator << (std::ostream & os, const widget & w) { return os << "A " << w.type << " widget named " << w.name; } int main() { handle<widget> wh = new widget(); wh->name = "joe"; wh->type = "blue"; std::cout << *wh << "\n"; } $ g++ -o t -ansi -pedantic -Wall t.cc $ ./t A blue widget named joe $
$ cat t.cc struct widget { std::string name; std::string type; }; int main() { handle<widget> wh = new widget(); wh->name = "joe"; wh->type = "blue"; std::cout << *wh << "\n"; } $ g++ -o t -ansi -pedantic -Wall t.cc t.cc: In copy constructor handle<T>::handle(const handle<T>&) [with T = widget]: t.cc:58: instantiated from here t.cc:16: no matching function for call to widget::clone() $
template <typename T> class Handle { T * tp size_t * ref_cntp; public Handle() Handle(T *) Handle (const Handle &) Handle & operator = (const Handle &) ~Handle() operator bool() const T & operator * () const T * operator -> () const }
handle() : tp(0), ref_cntp(new size_t(1)) { }
handle(T * tp) : tp(tp), ref_cntp(new size_t(1)) { }
~handle(void) if (--*ref_cntp == 0) delete tp delete ref_cntp
handle & operator = (const handle & th) ++*th.ref_cntp if (--*ref_cntp == 0) delete ref_cntp delete tp ref_cntp = th.ref_cntp tp = th.tp return *this
$ cat t.cc int main() { handle<widget> w1h = new widget(); w1h->name = "joe"; w1h->type = "blue"; handle<widget> w2h = w1h; w2h->type = "green"; std::cout << "w1h: " << *w1h << ".\n"; std::cout << "w2h: " << *w2h << ".\n"; } $ g++ -o t -ansi -pedantic -Wall t.cc $ ./t wh1: A green widget named joe. wh2: A green widget named joe. $
clone()
function.
template < typename T > void Handle<T>::clone(void) if (*ref_cntp != 1) --*ref_cntp ref_cntp = new size_t(1) if (tp) tp = tp->clone()
$ cat t.cc int main() { handle<widget> w1h = new widget(); w1h->name = "joe"; w1h->type = "blue"; handle<widget> w2h = w1h; w2h.clone(); w2h->type = "green"; std::cout << "w1h: " << *w1h << ".\n"; std::cout << "w2h: " << *w2h << ".\n"; } $ g++ -o t -ansi -pedantic -Wall t.cc $ ./t w1h: A blue widget named joe. w2h: A green widget named joe. $
See the complete code.
This page last modified on 28 April 2002.