471,863 Members | 1,012 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,863 software developers and data experts.

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 3157
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
NeoPa
reply views Thread by NeoPa | last post: by
aboka
reply views Thread by aboka | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.