|
Boost : |
From: Peter Dimov (pdimov_at_[hidden])
Date: 2003-01-31 07:09:54
From: "David B. Held" <dheld_at_[hidden]>
>
> smart_ptr(P p)
> : storage(p), ownership(p), checking(), conversion()
> { checking::on_init(p) }
smart_ptr(P p)
: storage(p), ownership(p), checking(p), conversion()
{}
is nicer. Maybe even conversion(p), for consistency. :-)
But that's not what I have in mind. There are a number of pitfalls awaiting
you.
Consider the converting move constructor:
smart_ptr(smart_ptr & rhs)
: storage(rhs), ownership(rhs), checking(rhs), conversion(rhs)
{}
(template parameters omitted for brevity)
Its purpose is to take ownership away from the auto_ptr-like rhs (you wanted
to support that) and construct a counted_ptr. As storage is constructed
first, it needs to move from rhs.storage; now when ownership throws,
rhs.storage will be left empty, and the object is gone. This is not that big
of a problem... provided that the other rhs policies can handle storage
being zeroed.
Weak pointers are another interesting case, assuming you want to support
them. A weak_ptr storage can't be copied safely, as the pointer may have
been deleted. If you look at shared_ptr::shared_ptr(weak_ptr const &),
you'll see that it copies the count first (its "ownership policy"), and then
proceeds to copy px (its "storage policy"). weak_ptr's converting
constructor does something similar.
Also:
smart_ptr::~smart_ptr()
{
if (!ownership_policy::release(get_impl(*this)))
{
storage_policy::release();
}
}
It's difficult to supply a get_impl for a weak pointer, since the returned
pointer can be invalidated at any time by a different thread. That's why
weak_ptr doesn't have (no longer has) one.
In short, trying to support auto_ptr, shared_ptr, and weak_ptr will either
destroy the design, or make it stronger. :-)
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk