2012-12-24 73 views
2

理查德·吉勒姆在他"The Anatomy of the Assignment Operator"可能作出錯誤陳述時,他說了這樣,就在他的論文開始:我的錯誤信息是否正確?

「一個正確的答案,這個問題會是這個樣子:」

TFoo&TFoo::operator=(const TFoo& that) 
{ 
    if (this != &that) 
    { 
     TBar* bar1 = 0; 
     TBar* bar2 = 0; 

     try 
     { 
      bar1 = new TBar(*that.fBar1); 
      bar2 = new TBar(*that.fBar2); 
     } 
     catch (...) 
     { 
      delete bar1; 
      delete bar2; 
      throw; 
     } 

     TSuperFoo::operator=(that); 
     delete fBar1; 
     fBar1 = bar1; 
     delete fBar2; 
     fBar2 = bar2; 
    } 
    return *this; 
} 

我認爲作者是錯誤的,因爲如果TSuperFoo::operator=()拋出,bar1bar2會泄漏。

+2

Wow'try-catch',這必須是寫作_exception safe_ code的_worst_方式... –

+0

本文後面的作者提供了一個使用auto_ptr的解決方案,我認爲這是正確的。 – Belloc

+1

'auto_ptr's?那些已被棄用? –

回答

1

將不會有任何內存泄漏,如果它看起來像這樣:

Tbar* pBar = NULL; 

try 
{ 
    pBar = new Tbar(); 
} 
catch (...) 
{ 
    delete pBar; // clean memory if it was allocated 
    throw;   // error was not handled properly, throw it to caller 
} 

delete pBar;  // no exception was caught, clean the memory 

但情況,最後delete之前,還有另一種代碼可能拋出一個異常,比你說的對,並有確實可能的路徑導致內存泄漏,因爲在這種情況下分配的內存永遠不會被清理。

人們編寫的代碼不使用這種語言提供的強大功能來避免這種醜陋的內存管理,這只是令人傷心。通常任何具有自動存儲持續時間的對象都已足夠,並且您會發現自己遵循RAII成語,或者在需要動態分配的情況下,那麼將這些裸指針與某些對象包裝在一起是個好主意......智能指針幫助了很多。

+0

指向RAII的+1 –

+0

OP指出'TSuperFoo :: operator ='可能會在'try-catch'之外拋出, –

+0

@ K-ballo對不起,我沒有注意到它。感謝您指出,我編輯了答案,現在應該沒問題:) – LihO