Re: Strong exception safety guaranty - Did I forget something ?
* Vincent Jacques:
[All code in this post is here only for illustration and may not compile
as is]
I'm writing a class with value semantic, and I want its public interface
to provide the strong exception safety guaranty (if a public operation
fails for any reason, then an exception is thrown, and the object is
left in its previous state)
My class's data members are standard containers and built-in types. For
the question, let's assume
typedef std::vector< int > vect;
class my_class
{
public:
my_class();
// ~my_class(); // Default implementation ok
// my_class( const my_class& ); // Default implementation ok
my_class& operator=( const my_class& );
public:
void modify();
private:
vect compute_modified_vect();
private:
bool my_bool;
vect my_vect;
};
vect my_class::compute_modified_vect()
{
vect new_vect;
// No special care about exception safety
// while modifying new_vect
return new_vect;
}
void my_class::modify()
{
compute_modified_vect().swap( my_vect );
m_bool = true;
}
my_class& my_class::operator=( const my_class& i )
{
vect new_vect( i.my_vect );
new_vect.swap( my_vect );
my_bool = i.my_bool;
return *this;
}
*The questions*
1) Do I really have to write operator= ?
Yes, unless you have guaranteed termination on bad_alloc exception (which is a
good idea, replace new_handler) you have to provide your own =, since you have
two interdependent data items, where assignment of one of them might throw. If
that is assigned last by built-in operator=, bye bye.
The above operator= should work nicely, but is too complicated for my taste.
I'd just use the usual swap idiom,
void my_class.swap( my_class& other ) throw()
{
my_vect.swap( other );
std::swap( my_bool, other.my_bool );
}
my_class& operator=( my_class other )
{
swap( other ); return *this;
}
As far as I know, the default
copy assignment operator gives no guaranty about exception safety, but I
may have missed something.
No, it doesn't provide any exception safety guarantees.
2) Is my implementation of operator= correct ?
It provides strong exception guarantee, yes, but it's brittle and complicated.
Brittle because it depends strongly on the order that otherwise independent
assignment are done. Someone comes along and changes the order, perhaps due to
introducing some additional data member, bye bye.
3) Since I thought very late in my conception that I may have to write
operator=, I wonder if there are other operations that I should write.
No, except the swap operation shown above.
4) Is my implementation of my_class::modify correct ?
It provides strong exception guarantee, yes.
5) Any other suggestion/comment ?
No.
Cheers, & hth.,
- Alf
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?