Strong exception safety guaranty - Did I forget something ?

V

Vincent Jacques

Hello all,

[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::eek:perator=( 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= ? As far as I know, the default
copy assignment operator gives no guaranty about exception safety, but I
may have missed something.

2) Is my implementation of operator= correct ?

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.

4) Is my implementation of my_class::modify correct ?

5) Any other suggestion/comment ?

Many thanks,
 
V

Vincent Jacques

Alf P. Steinbach a écrit :
The above operator= should work nicely, but is too complicated for my
taste.

I'd just use the usual swap idiom,

Thanks for the suggestion. Providing a swap function is anyway something
that I would have had to do later.

Cheers,
 
J

James Kanze

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::eek:perator=( 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= ? As far as I know, the
default copy assignment operator gives no guaranty about
exception safety, but I may have missed something.

The default copy assignment operator gives no direct guarantee,
but its semantics are strictly specified. In this case, it will
do the equivalent of:

my_bool = i.my_bool ;
my_vect = i.my_vect ;

In other words, it is guaranteed to modify my_bool first, so if
the copy assignment of my_vect throws (and it can throw),
my_bool will be modified, by not my_vect. In addition, as far
as I can tell, std::vector doesn't give the strong guarantee for
assignment either, so yes, you have to write the copy assignment
operator yourself.

Note that if the order of the members of the class was inversed,
and std::vector did give the strong guarantee (and most
implementations do in practice), you wouldn't have to provide
the operator yourself. I still would, however, since it makes
it much clearer.
2) Is my implementation of operator= correct ?
Yes.

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.

Any operator which modifies an existing object. In practice,
the copy assignment operator is the only one which will be
automatically generated.
4) Is my implementation of my_class::modify correct ?
Yes.

5) Any other suggestion/comment ?

You might really ask yourself if you need the strong guarantee.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top