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;
}
[/Code]


thanks in advance,
George

Re: using swap to make assignment operator exception safe by Igor

Igor
Tue Jan 08 07:58:02 CST 2008

"George" <George@discussions.microsoft.com> wrote in message
news:E09CA37A-D791-4FBB-A69C-E436D9EE1EB8@microsoft.com
> 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.

Not an assignment - initialization, using the copy constructor.
Otherwise you will enter infinite recursion, repeatedly invoking
assignment operator.

> 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.

Correct.

> [Code]
> class A;
> A& A::operator= (const A& a)
> {
> A temp;
> temp = a; // exception may be thrown

You want

A temp = a;

Otherwise you would have infinite recursion.

> swap (*this, temp);

Normally, class A would have a member swap() (doing something specific
to this class) and you would call

swap(temp);

Generic std::swap uses the class' copy constructor and assignment
operation, which again will lead to infinite recursion. For the code to
work as written, there should be a specialization of std::swap for class
A, or a non-template overload taking refererences to A as parameters.

> return *this;
> }
> [/Code]

--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925



Re: using swap to make assignment operator exception safe by George

George
Tue Jan 08 08:23:03 CST 2008

Thanks for your advice, so wonderful!


Your suggestion is if I need to utilize such swap in my class, I'd better
implement a customize swap member function other than utilizing std::swap?


regards,
George

"Igor Tandetnik" wrote:

> "George" <George@discussions.microsoft.com> wrote in message
> news:E09CA37A-D791-4FBB-A69C-E436D9EE1EB8@microsoft.com
> > 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.
>
> Not an assignment - initialization, using the copy constructor.
> Otherwise you will enter infinite recursion, repeatedly invoking
> assignment operator.
>
> > 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.
>
> Correct.
>
> > [Code]
> > class A;
> > A& A::operator= (const A& a)
> > {
> > A temp;
> > temp = a; // exception may be thrown
>
> You want
>
> A temp = a;
>
> Otherwise you would have infinite recursion.
>
> > swap (*this, temp);
>
> Normally, class A would have a member swap() (doing something specific
> to this class) and you would call
>
> swap(temp);
>
> Generic std::swap uses the class' copy constructor and assignment
> operation, which again will lead to infinite recursion. For the code to
> work as written, there should be a specialization of std::swap for class
> A, or a non-template overload taking refererences to A as parameters.
>
> > return *this;
> > }
> > [/Code]
>
> --
> With best wishes,
> Igor Tandetnik
>
> With sufficient thrust, pigs fly just fine. However, this is not
> necessarily a good idea. It is hard to be sure where they are going to
> land, and it could be dangerous sitting under them as they fly
> overhead. -- RFC 1925
>
>
>

Re: using swap to make assignment operator exception safe by Igor

Igor
Tue Jan 08 13:44:36 CST 2008

George <George@discussions.microsoft.com> wrote:
> Your suggestion is if I need to utilize such swap in my class, I'd
> better implement a customize swap member function other than
> utilizing std::swap?

Again - std::swap uses your own copy constructor and assignment
operator. It's nothing more than

template <typename T>
void swap(T& a, T&b) {
T temp = a;
a = b;
b = temp;
}

You can't call generic std::swap from your operator=, since std::swap
will just turn around and call operator= right back. You need a custom
implementation of swap that knows the internals of your class (usually
packaged as a member function). See for example std::vector::swap()
(which simply swaps pointers to memory buffers maintained by
std::vector, and thus is guaranteed not to throw).
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925



Re: using swap to make assignment operator exception safe by George

George
Tue Jan 08 21:49:00 CST 2008

Thanks Igor,


Do you think it is good idea to invoke class members' individual swap
function to avoid recursion?

(in my own application's class hierarchy, I will implement all swap
functions for all classes. So, swap will be invoked until POD or STL built-in
types.)


regards,
George

"Igor Tandetnik" wrote:

> George <George@discussions.microsoft.com> wrote:
> > Your suggestion is if I need to utilize such swap in my class, I'd
> > better implement a customize swap member function other than
> > utilizing std::swap?
>
> Again - std::swap uses your own copy constructor and assignment
> operator. It's nothing more than
>
> template <typename T>
> void swap(T& a, T&b) {
> T temp = a;
> a = b;
> b = temp;
> }
>
> You can't call generic std::swap from your operator=, since std::swap
> will just turn around and call operator= right back. You need a custom
> implementation of swap that knows the internals of your class (usually
> packaged as a member function). See for example std::vector::swap()
> (which simply swaps pointers to memory buffers maintained by
> std::vector, and thus is guaranteed not to throw).
> --
> With best wishes,
> Igor Tandetnik
>
> With sufficient thrust, pigs fly just fine. However, this is not
> necessarily a good idea. It is hard to be sure where they are going to
> land, and it could be dangerous sitting under them as they fly
> overhead. -- RFC 1925
>
>
>

Re: using swap to make assignment operator exception safe by Igor

Igor
Tue Jan 08 22:33:46 CST 2008

"George" <George@discussions.microsoft.com> wrote in message
news:3FF0052E-A8D0-459A-A706-8D7280040453@microsoft.com
> Do you think it is good idea to invoke class members' individual swap
> function to avoid recursion?
>
> (in my own application's class hierarchy, I will implement all swap
> functions for all classes. So, swap will be invoked until POD or STL
> built-in types.)

Sounds good to me.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925



Re: using swap to make assignment operator exception safe by George

George
Tue Jan 08 23:11:00 CST 2008

Thanks for your confirmation, Igor!


regards,
George

"Igor Tandetnik" wrote:

> "George" <George@discussions.microsoft.com> wrote in message
> news:3FF0052E-A8D0-459A-A706-8D7280040453@microsoft.com
> > Do you think it is good idea to invoke class members' individual swap
> > function to avoid recursion?
> >
> > (in my own application's class hierarchy, I will implement all swap
> > functions for all classes. So, swap will be invoked until POD or STL
> > built-in types.)
>
> Sounds good to me.
> --
> With best wishes,
> Igor Tandetnik
>
> With sufficient thrust, pigs fly just fine. However, this is not
> necessarily a good idea. It is hard to be sure where they are going to
> land, and it could be dangerous sitting under them as they fly
> overhead. -- RFC 1925
>
>
>