"David Abrahams" <[EMAIL PROTECTED]> wrote in message [EMAIL PROTECTED]">news:[EMAIL PROTECTED]... > > [...] > > Unfortunately, StoragePolicy doesn't know when other c'tors have > > failed. The only one who does is smart_ptr, which is why it seems > > I have to either A) use a function try block to inform StoragePolicy > > that someone else has failed, and clean up appropriately, > > Why not just arrange for StoragePolicy to be the first constructed?
smart_ptr(T* p) : storage(p), ownership(p), conversion(), checking() { ... } Suppose storage(p) succeeds, but ownership(p) throws (such as while allocating a count). You can't rely on ~storage() to do cleanup, because storage doesn't know what the ownership strategy is. It only knows about storage. Here's what ~smart_ptr() looks like: ~smart_ptr() { if (ownership_policy::release(get_impl(*this))) { storage_policy::destroy(); } } So you see, storage_policy must be told when to do cleanup by smart_ptr (that's the principle of orthogonal policies). It's easy enough to write storage_policy::storage_policy(T* p) to clean up after itself if *it* throws. But getting it to clean up after *another* policy is the trick. Obviously, if one of the other c'tors throws, ~smart_ptr() never gets called, so how do we tell storage_policy that a failure occurred, and it needs to clean up? The only way I can see is to use a function try block: smart_ptr(T* p) try : storage_policy(p), ownership(p), conversion(), checking() { ... } catch { storage_policy::destroy(); } Unfortunately, that's totally Greek to bcc 5.5 (and probably vc++, though I don't have access to it right now), not to mention that it requires storage_policy(p) to be no-throw. > > or B) not use initializer lists, and do all the work in the c'tor > > body of smart_ptr. > > I don't see how B can work; the resource will be unmanaged at > least until the body is entered, while all the bases and members > are constructed. That can only work if the default c'tors are no-throw, which would mean special-casing ref_counted to not allocate a count until it actually receives a pointer. But it would also make the rest of the functions in ref_counted bulkier because now you have to detect a null count pointer. Otherwise, you would have to set the count pointer to null, and have the body of smart_ptr ask ref_counted if he was built properly. Quite messy. I don't see any nice solutions to this problem. Dave _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost