using swap to make assignment operator exception safe

G

George2

Hello everyone,


The following swap technique is used to make assignment operator
exception safe (means even if there is exception, the current object
instance's state is invariant).

It used a temporary object "temp" in this sample, and assignment is
made on a to temp ar first. Even if there is exception, the current
this object's state is not corrupted.

My question is, the pattern works only if there is no exception thrown
by swap function. If there are exception in swap function, the state
of current object instance may still be corrupted (swap may invoke the
assignment operator of member variables). Is my understanding correct?

Code:
class A;
A& A::operator= (const A& a)
{
    A temp;
    temp = a; // exception may be thrown
    swap (*this, temp);
    return *this;
}


thanks in advance,
George
 
J

jkherciueh

George2 said:
Hello everyone,


The following swap technique is used to make assignment operator
exception safe (means even if there is exception, the current object
instance's state is invariant).

It used a temporary object "temp" in this sample, and assignment is
made on a to temp ar first. Even if there is exception, the current
this object's state is not corrupted.

My question is, the pattern works only if there is no exception thrown
by swap function. If there are exception in swap function, the state
of current object instance may still be corrupted (swap may invoke the
assignment operator of member variables). Is my understanding correct?
[snip]

Yes.

Note, however, that swap does not throw for built-in types and for standard
containers. Moreover, given a class

class SomeClass {

type_1 member_1;
type_2 member_2;
...

};

the obvious implementation of swap is

swap ( SomeClass & lhs, SomeClass & rhs ) {
swap( lhs.member_1, rhs.member_1 );
swap( lhs.member_2, rhs.member_2 );
...
}

And this implementation will not throw provided that the swap functions for
type_1, type_2, ... do not throw. Thus, in principle, swap could be
implemented as a no-throw operation for all types.

However, there is a catch: libraries and other code outside your control. If
type_3 is defined in some third-party library and does not provide a
no-throw swap, the argument breaks down and you might have to work around
the problems.

(Since the code for swap conforms to a uniform pattern, one has to wonder if
it would be a good idea to change the language so that the compiler will
generate a default swap function for each type very much like the compiler
provided copy-constructor and assignment operator.)


Best

Kai-Uwe Bux
 
R

Ron Natalie

George2 said:
Code:
class A;
A& A::operator= (const A& a)
{
A temp;
temp = a; // exception may be thrown
swap (*this, temp);
return *this;
}
The above code loops infinitely. The "temp = a"
line calls the assignment operator again.

The idiom you want is:

A& A::eek:perator=( const T& other )
{
A temp( other );
swap(*this, temp );
return *this;
}

Your assumptions are wrong. The code is safe
regardless whether A's copy constructor or swap
throws exceptions as long as they are internally
exception safe.
 
A

asterisc

George2 said:
Code:
class A;
A& A::operator= (const A& a)
{
A temp;
temp = a; // exception may be thrown
swap (*this, temp);
return *this;
}

The above code loops infinitely. The "temp = a"
line calls the assignment operator again.

The idiom you want is:

A& A::eek:perator=( const T& other )
{
A temp( other );
swap(*this, temp );
return *this;
}

Your assumptions are wrong. The code is safe
regardless whether A's copy constructor or swap
throws exceptions as long as they are internally
exception safe.

swap() should never throw any exceptions.

Probably he wanted to write:
A temp = a; // exception may be thrown
 
D

dizzy

Ron said:
The idiom you want is:

A& A::eek:perator=( const T& other )
{
A temp( other );
swap(*this, temp );
return *this;
}

I prefer the shoter version:
A& A::eek:perator=(A src)
{
swap(*this, src);
return *this;
}

Should be semantically equivalent to your version.
 

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

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top