Hello everyone,
http://www.gotw.ca/gotw/059.htm
The reason why we can not write an exception safe copy assignment for class Widget, is because (suppose we assign t1_, then assign t2_) if T1:perator=() does not throw exception, and T2:perator=() throws exception, then since all operations on T1 may throw, it means we can not find any operations on T1 which could rollback the original status to T1 without exception thrown (if exception is thrown during rollback, means rollback is not successful, and T1 will be in an in-consistent status which is different from original status -- which violates the strong exception safe guideline).
My understanding correct?
I quote the related paragraph below as well.
--------------------
3. Consider the following class:
Assume that any T1 or T2 operation might throw. Without changing the structure of the class, is it possible to write a strongly exception-safe Widget:perator=( const Widget& )? Why or why not? Draw conclusions.
Short answer: In general, no, it can't be done without changing the structure of Widget.
In the Example 3 case, it's not possible to write a strongly exception-safe Widget:perator=() because there's no way that we can change the state of both of the t1_ and t2_ members atomically. Say that we attempt to change t1_, then attempt to change t2_. The problem is twofold:
1. If the attempt to change t1_ throws, t1_ must be unchanged. That is, to make Widget:perator=() strongly exception-safe relies fundamentally on the exception safety guarantees provided by T1, namely that T1:perator=() (or whatever mutating function we are using) either succeeds or does not change its target. This comes close to requiring the strong guarantee of T1:perator=(). (The same reasoning applies to T2:perator=().)
2. If the attempt to change t1_ succeeds, but the attempt to change t2_ throws, we've entered a "halfway" state and cannot in general roll back the change already made to t1_.
--------------------
thanks in advance,
George
http://www.gotw.ca/gotw/059.htm
The reason why we can not write an exception safe copy assignment for class Widget, is because (suppose we assign t1_, then assign t2_) if T1:perator=() does not throw exception, and T2:perator=() throws exception, then since all operations on T1 may throw, it means we can not find any operations on T1 which could rollback the original status to T1 without exception thrown (if exception is thrown during rollback, means rollback is not successful, and T1 will be in an in-consistent status which is different from original status -- which violates the strong exception safe guideline).
My understanding correct?
I quote the related paragraph below as well.
--------------------
3. Consider the following class:
Code:
// Example 3: The Cargill Widget Example
//
class Widget
{
// ...
private:
T1 t1_;
T2 t2_;
};
Assume that any T1 or T2 operation might throw. Without changing the structure of the class, is it possible to write a strongly exception-safe Widget:perator=( const Widget& )? Why or why not? Draw conclusions.
Short answer: In general, no, it can't be done without changing the structure of Widget.
In the Example 3 case, it's not possible to write a strongly exception-safe Widget:perator=() because there's no way that we can change the state of both of the t1_ and t2_ members atomically. Say that we attempt to change t1_, then attempt to change t2_. The problem is twofold:
1. If the attempt to change t1_ throws, t1_ must be unchanged. That is, to make Widget:perator=() strongly exception-safe relies fundamentally on the exception safety guarantees provided by T1, namely that T1:perator=() (or whatever mutating function we are using) either succeeds or does not change its target. This comes close to requiring the strong guarantee of T1:perator=(). (The same reasoning applies to T2:perator=().)
2. If the attempt to change t1_ succeeds, but the attempt to change t2_ throws, we've entered a "halfway" state and cannot in general roll back the change already made to t1_.
--------------------
thanks in advance,
George