2016-08-25 47 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)遇到了例外,上面的代碼可以做到異常安全,鉛可以保持相同的,而不是指向NULL,但怎麼樣,爲什麼呢?有人可以幫助我嗎?謝謝!

+13

這是書的確切文字?這聽起來不像是可以通過編輯完成的那種文本。如果可能,請引用*確切的文字*。 –

+0

什麼樣的*異常安全*?強大?基本? NoExcept? –

+0

我懷疑這本書說'&rhs == this',而不是'rhs == * this'。 – molbdnilo

回答

4

雖然這個問題可能不是太精確,我想我還是有一點:

試想一下,代碼會被寫成如下:

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; 
} 

會發生什麼,如果new Bitamp()失敗一個例外 - 然後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)失敗(拋出異常),有沒有Bitmap實例了內部Widgetpb指向的Bitmap刪除實例。這將在銷燬Widget時崩潰。