|
Boost : |
From: Gennadiy Rozental (rogeeff_at_[hidden])
Date: 2002-05-08 00:05:53
"Gennadiy Rozental" <rogeeff_at_[hidden]> wrote in message
news:ab5j3c$oha$1_at_main.gmane.org...
Yet another topic I was too tired to talk last time:
Topic 7: Exception safety
IMO current design may have problems with exception safety in constructors.
While we talking about this, remember, that smart_ptr inherit
PoliciesAdaptor so we don't really know order of Policies constructors.
1. Default Constructor
Seems ok. If every policy cleanly release resources allocated in default
constructor in destructor.
2. pointer_type constructor
In my version it look like this:
smart_ptr( pointer_type const& rhs )
{
// 1. Default constructors
storage_policy::init( rhs );
// 2. method init
checking_policy::on_init( storage_policy::storage() );
// 3. method on_init
ownership_policy::first_reference( storage_policy::storage() ); //
4. method first_reference
}
Here exception may be thrown on any step. We will need try catch block
probably. There 3 issues here:
a. Do we need to catch anything? Why?
We may need to catch to do something with the resource passed to us in
the constructor. In most cases we want to destroy it. Though in some cases
we won't. The answer really user-dependent.
b. What should we guard here? And how?
Everything. So we need function try block like this:
smart_ptr( pointer_type const& rhs )
try
: PoliciesAdaptor()
{
storage_policy::init( rhs );
checking_policy::on_init( storage_policy::storage() );
ownership_policy::first_reference( storage_policy::storage() );
}
catch( ???) {
???
}
Next question what to catch? The most obvious answer "...", since we
don't really care.
c. How to destroy the resource?
smart_ptr constructor does not really know how to destroy the
resource. It is part of StoragePolicy logic. But storage policy instance
does not exist at the time (or may not have a pointer stored). So we need
some static interface from storage policy that will destroy supplied
variable of pointer_type. Note tat this is not a stored_type. So we may not
probably be able to reuse existent destroy interface (by means of making it
static and adding pointer_type argument), since some policies may want to
destroy namely stored_type.. So at the end we should have something like
this:
smart_ptr( pointer_type const& rhs )
try
: PoliciesAdaptor()
{
storage_policy::init( rhs );
checking_policy::on_init( storage_policy::storage() );
ownership_policy::first_reference( storage_policy::storage() );
}
catch(...) {
StoragePolicy::destroy( rhs )
}
3. Copy constructor.
Here a lot of bad thing may happened. Couple examples:
a. ref_linked ownership policy constructor passed well, while storage
policy constructor is failing. What are we gonna do with links?
b. deep copy storage policy passed well, ownership policy is failing. How
is gonna release the memory?
I do not know yet what to do here. Any suggestions?
Gennadiy.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk