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.