2011-05-03 35 views
1

我目前正在尋找最流行的智能PTR實現,如提升共享和弱指針以及loki Smart and Strong pointer,因爲我想實現我自己的,並從我的理解Loki強指針看起來對我不安全,但我寧願認爲我理解它錯了,所以我想討論它是否安全。爲什麼我認爲這是不是安全的原因是,據我可以告訴它不能治療弱指針(這是一個StrongPtr,其中false表示其弱)有足夠的護理:C++:Loki StrongPtr對我來說看起來不安全,是這樣嗎?

例如在解引用功能:

PointerType operator ->() 
{ 
KP::OnDereference(GetPointer()); //this only asserts by default as far as i know 
//could be invalidated right here 
return GetPointer(); 
} 

在多線程環境中,弱指針隨時可能失效,因此該函數可能會返回一個無效的Ptr。

據我的理解,你要麼必須創建一個你要解除引用的ptr的strongPtr實例,以確保它不會在半途中失效。我認爲這也是boost不允許你在不創建shared_ptr實例的情況下解引用weak_ptr的原因。 Lokis StrongPtr構造函數遭受同樣的問題,我認爲。

這是一個問題,還是我閱讀src錯誤?

+0

看起來確實不安全,特別是因爲沒有創建強指針,對象可能會在您返回之前刪除,而且在用戶使用它時也會被刪除(ouch)。也許多線程很難的好例子! – 2011-05-03 09:51:43

+0

那麼,你指出,它不是**線**安全。我不知道它是否承諾過線程安全(它看起來不像你展示的代碼片段)。 (_unrelated:你的問題標題完全是修辭和自我傾向_) – sehe 2011-05-03 09:55:00

+0

我認爲你有點太多的課。沒有鎖定,你無法保證沒有任何邪惡的事情發生在你不擁有的東西上。不管你希望在操作符中加入更好的檢查 - >使得實際的解引用完全安全,它可能在您取消引用指針並仍在成員函數調用之後仍然被銷燬。就是這樣。 – Damon 2011-05-03 09:57:45

回答

3

關於使用assert,這是一個編程錯誤對空StrongPtr<>實例中使用operator->;即負責確保StrongPtr<>實例在取消引用前是非空的,因此是調用者的責任責任。爲什麼需要超過assert?也就是說,如果認爲一些比assert更合適的行爲,那麼這正是政策的目的。

這是先決條件和後置條件之間的根本區別;這裏有一個很長但很好的主題:comp.lang.c++.moderated: Exceptions。詳細閱讀D. Abrahams的文章,他詳細解釋了我所說的理解事實。 ; - ]

關於StrongPtr<>的線程安全性,我懷疑大部分Loki早於任何嚴重的線程安全問題;另一方面,boost::shared_ptr<>std::shared_ptr<>明確保證是線程安全的,所以我確信他們的實現使得「更好」(雖然更復雜)的學習基礎。

+0

我不同意,正如你所看到的,斷言根本不足以確保上述情況中的任何事情。此外檢查引用計數之前不會改變任何東西。如上所述,只要我可以在多線程環境中看到,唯一可以做的就是手動保留referencecount,或者在解引用弱ptr之前通過創建Strong copy來保留referencecount。我非常確定你不能安全地用檢查策略解決問題,因爲你必須返回某種類型的代理對象,它在內部存儲一個強指針以保留引用計數。 – moka 2011-05-03 10:45:44

+0

@ user300713:問題是,'assert' *不能確保任何內容* - 它提醒程序員*確保某些東西(即StrongPtr <>'非空)。再次,在空的'StrongPtr <>'實例上使用'operator->'是一個編程錯誤,並且不存在可以防止編程錯誤的機制。你可以做的最好的事情是讓程序員知道他們有一個編程錯誤,最好以避免降低運行時性能 - 即'assert'的方式。 – ildjarn 2011-05-03 11:04:29

+0

好吧,我從來沒有說過斷言是爲了確保一切。我只是說,在我剛剛概述的情況下,它甚至不會讓程序員知道任何事情。 – moka 2011-05-03 11:08:21

0

仔細閱讀後,我想我看到了理由。

StrongPtr對象是雙重的,因爲它們代表StrongWeak引用。

assert的機制在Strong版本上很有效。在Weak版本上,調用者的責任是確保所引用的對象的活動時間足夠長。這樣就可以實現兩種:通過創建Strong實例

  • 手動

    • 自動,如果你知道你有一個Strong版本,

    好處WRT std::shared_ptr是,你可以避開創建當你已經知道這個物品會超過你的使用時,這個新的物品。這是一個有爭議的設計決策,但對專家來說非常有用(其中Alexandrescu毫無疑問是)。它可能不是針對普通用戶(我們)的目標,因爲這些用戶強制使用Strong版本會更好。

    人們也可以爭辯說,事後看來,批評總是容易的。儘管它的偉大,Loki已經很老了。

  • +0

    好的問題是,StrongPtr的設計(順便說一句,Rich Sposato在2006年寫的)就是你甚至不能安全地從一個弱版本創建一個強版本。 – moka 2011-05-03 12:27:34

    +0

    @ user300713:對,雖然這可以很容易地添加。 – 2011-05-03 14:12:32

    相關問題