|
Boost : |
From: David B. Held (dheld_at_[hidden])
Date: 2003-01-30 02:17:09
"Andrei Alexandrescu" <andrewalex_at_[hidden]> wrote in message
news:b1aact$imm$1_at_main.gmane.org...
> [...]
> I suggest we just make an explicit function acquire() for the ownership
> policy and have all of its other member functions assume acquire() was
> called.
Unfortunately, this requires no-throw default construction of all policies.
Since ref_counted allocates the count even in the default case, we have
to silence any std::bad_alloc's that get thrown. That leaves us with
checking if we actually have a count or not. We either have to validate
the count pointer in every member function, or call a special function that
does nothing but check to see if ownership_policy() was successful or
not. Can we say 'ugly'?? Let me state the problem in C++:
smart_ptr(P p)
: storage(), ownership(), conversion(), checking()
{
try
{
storage::acquire(p);
ownership::acquire(p);
checking::on_init(p);
}
catch (...)
{
storage::destroy();
}
}
If ownership() throws, p is leaked. So we have to make ownership() no-
throw:
ref_counted()
: pCount(0)
{ }
ref_counted(P p)
: pCount(new int(1))
{ }
void acquire(P p)
{
if (pCount) throw 0;
pCount = new int(1);
}
P clone(P p)
{
if (!pCount) throw 0;
++*pCount;
return p;
}
bool release(P p)
{
if (!pCount) throw 0;
if (!--*pCount)
{
delete pCount;
return true;
}
return false;
}
friend inline unsigned use_count(ref_counted const& p)
{ if (!p.pCount) throw 0; return *(p.pCount); }
Or, we could do it this way:
ref_counted()
: pCount(new (std::no_throw) int(1))
{ }
void acquire(P p)
{
if (!pCount) throw 0;
}
And then mandate that ownership_policy is not usable until acquire()
has been called, avoiding further checks for pCount == 0. Hopefully,
requiring all no-throw default c'tors will not impose an undue penalty
on policies.
Dave
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk