Item 39. Exception Safe Functions
The difficulty to write an exception security code is not to throw and capture an exception, but is to throw and capture things to do. When an exception is thrown
During the process of arriving the capture statement, the function executed during this period needs to clean any resources it used before the playback. Usually, this requires a film
Thinking and some common sense.
Taking String's assignment operation as an example: string & string :: operator = (const char * STR) {if (! Str) str = "; char * tmp = structure (new char [str) 1], STR) Delete [] s_; s_ = tmp; return * this;}
Char * TMP This intermediate variable seems to be a bit redundant, we "can" write this: string & string :: operator = (const char * str) {delete [] s_; if (! str) str = ""; s_ = strcpy (new Char [Strlen (STR) 1], STR); return * this;}
As so than? Delete [] According to the agreement, it can guarantee that there is no abnormality, but new [] may throw an exception. Whether it is unknown to the new memory is successful
Time, we released the memory of S_. Thus, the String object is in a Bad State. Herb Sutter tells us that in this case should be handled: First, those can be dealt with.
Often operation, followed by endless processes that cannot trigger an exception (first do anything cup Cause
Exception "Off to the Side" without Changing Important State, and the Use Operations That
CAN't throw an exception to finish up.).
Look at an example:
Write: void button :: setAction (const Action * newaction) {delete action_; // change state! Action_ = newaction-> clone (); // Then Maybe throw?}
Cuts: void button :: setAction (const action * newaction) {delete action_; try {action_ = newaction-> clone ();} catch (...) {action_ = 0; throw;}} simple correct way of writing : Void button :: setAction (const action * newaction) {action * temp = newaction-> clone (); // off to the side ... delete action_; // then change state! Action_ = Temp;