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(string str) : str(str)
cerr << "Creating a " << str << " widget"
~widget()
cerr << "Deleting a " << str << " widget"
widget * clone(void) const { return 0; }
const 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
string name;
string type;
widget * clone(void) const { return 0; }
std::ostream &
operator << (ostream & os, 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() $
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, ref_cntp
handle & operator = (const handle & th)
++*th.ref_cntp
if (--*ref_cntp == 0)
delete ref_cntp, 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 14 April 2003.