469,623 Members | 1,800 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,623 developers. It's quick & easy.

using swap to make assignment operator exception safe

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?

Expand|Select|Wrap|Line Numbers
  1. class A;
  2. A& A::operator= (const A& a)
  3. {
  4. A temp;
  5. temp = a; // exception may be thrown
  6. swap (*this, temp);
  7. return *this;
  8. }
  9.  

thanks in advance,
George
Jan 8 '08 #1
4 3072
George2 wrote:
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
Jan 8 '08 #2
George2 wrote:
>
Expand|Select|Wrap|Line Numbers
  1. class A;
  2. A& A::operator= (const A& a)
  3. {
  4.     A temp;
  5.     temp = a; // exception may be thrown
  6.     swap (*this, temp);
  7.     return *this;
  8. }
  9.  

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

The idiom you want is:

A& A::operator=( 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.

Jan 8 '08 #3
On Jan 8, 2:53 pm, Ron Natalie <r...@spamcop.netwrote:
George2 wrote:
Expand|Select|Wrap|Line Numbers
  1.  class A;
  2.  A& A::operator= (const A& a)
  3.  {
  4.      A temp;
  5.      temp = a; // exception may be thrown
  6.      swap (*this, temp);
  7.      return *this;
  8.  }
  9.  

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

The idiom you want is:

A& A::operator=( 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
Jan 8 '08 #4
Ron Natalie wrote:
The idiom you want is:

A& A::operator=( const T& other )
{
A temp( other );
swap(*this, temp );
return *this;
}
I prefer the shoter version:
A& A::operator=(A src)
{
swap(*this, src);
return *this;
}

Should be semantically equivalent to your version.

--
Dizzy

Jan 8 '08 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Davis King | last post: by
10 posts views Thread by Tony Johansson | last post: by
16 posts views Thread by Martin Jørgensen | last post: by
6 posts views Thread by Jack White | last post: by
1 post views Thread by ma740988 | last post: by
reply views Thread by gheharukoh7 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.