2015-12-22 51 views
7

異常是C++的重要組成部分,使用它的原因之一(我知道有很多更重要的原因)是爲了避免不必要的檢查,用很多if語句對代碼進行混淆(可能這是不正確的假設?)。爲什麼不std :: shared_ptr dereference拋出一個空指針異常(或類似)?

所以,現在我很好奇,爲什麼std::shared_ptr::operator*std::shared_ptr::operator->不拋出null_ptr_exception或類似?

+0

你有沒有發現一個智能指針,做所描述的行爲的實現? – aggsol

+0

@aggsol,不,我們最終使用現有的實現和模板策略來製作我們自己的版本 – Samaursa

回答

7

我的理解是,智能指針類的設計看起來像行爲指針一樣。考慮到這一指導設計原則,理想的遺留代碼可以簡單地使用等價所有權語義替換原始指針與智能指針的使用,代碼將與以前完全一樣。因此,改變取消引用智能指針的行爲不應該做任何額外的檢查或拋出異常(即由於原始指針不以這種方式表現)。

智能指針添加到標準的提議表示該設計決定(A Proposal to Add General Purpose Smart Pointers to the Library Technical Report):

III。設計決策

A.一般原則

  1. 「儘可能接近原始指針越好,但沒有接近」
+1

感謝您的回答。我必須承認,標準委員會的理由並不令人滿意。如果我們用智能指針代替遺留代碼,那麼'null_ptr_exception'將會被處理並且程序將會中斷(就像斷言一樣,儘管沒有展開的話就被授予了 - 然後,就像斷言一樣,這個異常可以被分解成由調試器)。 – Samaursa

+1

@Samaursa對於一個原始指針解引用空指針觸發未定義的行爲,程序可能看起來正常運行正常,但我理解你的觀點和沮喪。 –

4

如果需要每個解除引用共享指針來檢查nullptr並有條件地拋出異常,則可能會有大量冗餘檢查,代碼膨脹和開銷。當然 - 優化器可能會消除其中的一部分,但仍然是....相反,程序員希望在檢查一次之前檢查一次,但需要多次解除引用。

+0

但是,這不是針對異常/錯誤代碼的參數嗎? – Samaursa

+1

@Samaursa:不...引用原始指針或標準庫智能指針允許生成機器代碼,假設指針永遠不會爲nullptr - 該機器代碼運行速度快於需要檢查和避免的代碼(對於相同的代碼非nullptr的情況)分支到錯誤處理代碼。無論使用異常還是錯誤代碼(它們本身可能在速度和機器代碼大小上有所不同),都不會檢查/分支速度更快。 –

+0

我期望'unique_ptr'有一個斷言和'shared_ptr'(因爲它已經是一個很重的對象,引用計數和跟蹤'weak_ptr's)到'throw'。不過,由於指針解引用是一種非常常見的操作,因此這是有意義的。 – Samaursa