|
Boost : |
From: David B. Held (dheld_at_[hidden])
Date: 2003-01-29 19:24:53
"Andrei Alexandrescu" <andrewalex_at_[hidden]> wrote in message
news:b19mhu$9sm$1_at_main.gmane.org...
> [...]
> Ideally, SmartPtr should orchestrate the workings of the policies
> together while they are aloof of each other.
That's the gold standard, of course.
> [...]
> So my suggestion is to work around the language instead of
> breaking orthogonality gratuitously. I believe this is NOT an example
> when orthogonality plays against you.
Unfortunately, I'm not sure what you suggest as an exception-safe
implementation now. The function try block solution is right out, both
in practice (because most compilers fail to support it, and frankly, I
don't blame them), and in theory (destructors have been called on
fully constructed members/bases already anyway). It seems the only
"safe" solution is default construction with ownership transfer in the
body of the c'tor. Is this what you recommend? It requires expanding
the policy interface by adding new functions to storage_policy and
ownership_policy. I suppose we could do something like this:
void scalar_storage::acquire(stored_type const& p)
{
pointee_ = p;
}
template <typename U>
void ref_counted::acquire(U const& p)
{
}
template <typename U>
smart_ptr(U const& p)
{
try
{
storage_policy::acquire(p);
ownership_policy::aquire(p);
checking_policy::on_init(get_impl(*this));
}
catch (...)
{
storage_policy::destroy();
throw;
}
}
Ultimately, it's only slightly less efficient than the initializer list
form, and
now doesn't leak p when someone passes 'new X'. Orthogonality is
preserved, and angels from on high sing Hallelujah (ok, maybe the last
part is stretching it). Taking ownership probably should be a separate
step from construction anyway.
Dave
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk