"Andrei Alexandrescu" <[EMAIL PROTECTED]> wrote in message b1aact$imm$[EMAIL PROTECTED]">news:b1aact$imm$[EMAIL PROTECTED]... > [...] > 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 _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost