2016-08-25 12 views
-7

非常にストレートな質問です。なぜ過負荷演算子=例外安全を行う

class Bitmap {...}; 
class Widget { 
    ... 
    private: 
     Bitmap* pb; 
}; 

オーバーロードされたコピー割り当ての場合、本(Effective C++)は以下のように述べています。下のコードは例外安全です。

Widget& Widget::operator=(const Widget& rhs) { 
    if (rhs == *this) return; 
    Bitmap* pOrig = pb; //?? why remember the pb can do exception safety? 
    pb = new Bitmap(*rhs.pb); 
    delete pOrig; 
    return *this; 
    } 

ブックは言った:でも、新しいビットマップ(* rhs.pb)を介して例外を満たし、上記のコードは、例外安全性を行うことができ、PBはNULLへのポインタ、同じことをしませ保つことができますが、どのように、なぜ?誰かが私を助けることができますか?ありがとう!

+13

これは本の正確なテキストですか?それは編集を通してそれを作るテキストのようには聞こえません。可能であれば、*正確なテキスト*を引用してください。 –

+0

*どのような*例外安全*?強い?基本? NoExcept? –

+0

私はこの本は 'rhs == * this'ではなく、'&rhs == this'と言います。 – molbdnilo

答えて

4

が、私はまだポイントだと思う:

は想像を以下のように、コードが書かれていたであろう:new Bitamp()がで失敗した場合、どうなります

Widget& Widget::operator=(const Widget& rhs) 
{ 
    if (rhs == *this) // actually, you'd rather do &rhs == this! 
         // you don't want self-assignment 
     return; 
    delete pb; 
    pb = new Bitmap(*rhs.pb); 
    return *this; 
} 

例外 - pbは既に削除されており、無効なメモリを指しています!

ですから、最初のPBの値を覚えて、作成が例外で失敗した場合、あなたはthisを変更していないと、例外が発生した場合、それはでも有効です。

1

new Bitmap(*rhs.pb)の作成中に例外がスローされた場合、Widgetの状態は変更されません。

あなたは、単にnew Bitmap(*rhs.pb)を行う前にpbを削除した場合:

Widget& Widget::operator=(const Widget& rhs) { 
    if (rhs == *this) return; 
    delete pb; // unsafe 
    pb = new Bitmap(*rhs.pb); 
    return *this; 
    } 

そしてnew Bitmap(*rhs.pb)が失敗したが(例外をスロー)、そこWidgetの内側にもう何Bitmapインスタンスではない、とBitmapの削除されたインスタンスにpbポイント。これは、破壊中にクラッシュするWidget。質問があまりにも正確ではないかもしれませんが、

関連する問題