2011-07-28 43 views
1

通常我會遵循Google風格指南,我覺得它與我看到的東西很好地吻合。我也幾乎完全使用boost :: scoped_ptr,這樣只有一個管理員擁有特定對象的所有權。然後我傳遞裸指針,這個想法是我的項目的結構使得所有對象的管理者在使用它們的對象被銷燬後總是被銷燬。對scoped_ptr的弱引用?

http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Smart_Pointers

這是所有偉大的,但我只是一個討厭的小內存錯誤跺腳這裏的主人正巧在用它已刪除的對象之前被刪除咬傷。

現在,在大家上下跳躍之前,我是這種模式的傻瓜,爲什麼我不使用shared_ptr?等等,考慮一點,我不想擁有未定義的所有者語義。儘管shared_ptr會發現這種特殊情況,但它會向系統的用戶發送錯誤的消息。它說:「我不知道誰擁有這個,它可能是你!」

什麼可以幫助我會是一個弱指針的範圍指針。實際上,一個有弱引用列表的作用域指針,在作用域指針破壞時會被清除。這將允許單個所有權語義,但給予使用對象一個機會來解決我遇到的問題。

因此,在weak_ptr中,爲scoped_ptr和'next_weak_ptr'的額外'weak_refs'指針以及額外的指針開銷,這將使一個整潔的小單一所有者,多用戶結構。

它可能甚至可能只是一個調試功能,所以在'發佈'中,整個系統只會變回正常大小的scoped_ptr和弱參考的標準單指針。

所以.....畢竟這我的問題是:

  1. 是否有這樣的指針/彭定康已經在STL /升壓,我是 丟失,或者我應該推出自己的?
  2. 有沒有更好的辦法, 仍然符合我的單一所有權目標?

乾杯, 巴蒂爾

+2

我不知道標準或庫實現。如果你確實實現了你所描述的內容,那麼最終會得到一個類似於boost shared_ptr/weak_ptr的實現,因爲你可能想要檢測到有人從weak_ptr中獲取了原始指針並將其緩存。話雖如此,您可能只想使用shared_ptr/weak_ptr並在您的「管理器」中聲明其所保存的shared_ptr在您想銷燬該對象時是唯一的。 –

回答

6

  2.有沒有更好的辦法,仍然符合我的單一所有制的目標?

不要使用shared_ptr,但作爲一類部件,使得它是類的不變和公共接口的一部分僅公開的方式來獲得weak_ptr

當然,病理編碼​​可以保留自己shared_ptrweak_ptr只要他們想要的。我不建議在這裏保護馬基雅維利,而只是針對墨菲(用薩特的話)。另一方面,如果你的用例是異步的,那麼鎖定weak_ptr返回shared_ptr這一事實可能是一個特性!

+0

這實際上是隱藏所有權問題的好方法。我喜歡它:) – Shane

3

雖然shared_ptr會抓住這種特殊情況,但它會向系統的用戶發送錯誤的消息。它說:「我不知道誰擁有這個,它可能是你!「

一個shared_ptr並不意味着‘我不知道誰擁有這個’。這意味着」 我們自己這一點。」就因爲一個實體不具有獨佔所有權並不意味着可以擁有它。

一個shared_ptr的目的是爲了確保指針不能被破壞,直到大家誰股吧是一致認爲它應該被銷燬。

是否有這樣的指針/彭定康已經在stl/boost,我是missi ng,還是我應該自己推出?

您可以像使用scoped_ptr一樣使用shared_ptr。只是因爲它可以共享並不意味着你有分享它。這將是最簡單的工作方式;只是將單一所有權視爲慣例而不是API規定。然而,如果你需要一個單一所有者但指針很弱的指針,那麼Boost中就沒有一個指針了。

+0

嗨尼科爾,是的,我當時正在我有點聳人聽聞「我不知道誰擁有這個......」行,但,是的,你說得對;)至於你點,我開始重新思考我強制執行單一所有權的做法,並且只使用shared_ptr方法進行滾動。 – Shane

1

我不確定弱指針會有多大幫助。通常,如果組件X使用另一個組件Y,則必須通知X的消亡, 不僅僅是爲了使指針無效,而是可能從列表中移除它,或者改變它的操作模式,以便它不再需要 對象。很多年前,當我第一次開始使用C++時,發現了一大堆試圖找到一個好的通用解決方案的活動。 (當時問題是 稱爲關係管理。)據我所知,沒有好的通用解決方案被發現;至少,我在 上工作過的每個項目都使用了基於Observer模式的手工構建解決方案。

我的網站上有一個ManagedPtr,當它還在運行時,其行爲如您描述的那樣表現爲 。在實踐中,除了特定的導致它的 情況外,我從來沒有發現它的實際用途,因爲總是需要 通知。然而,這並不難實現; 受管理對象來自ManagedObject類,並獲取從它中取出的所有指針(ManagedPtr,而不是原始指針)。 指針本身已註冊ManagedObject課程,並且ManagedObject課程的 析構函數通過將實際指針設置爲空來訪問它們,並「斷開」 它們。當然,ManagedPtr 具有isValid函數,因此客戶端代碼可以在 取消引用之前進行測試。這種運作良好,(不管對象是如何 管理—我的大部分實體的對象「擁有」自己,並做了 delete this是針對一些特定的輸入),但你往往 泄漏無效ManagedPtr(例如,每當客戶端將指針 保存在某種類型的容器中,因爲它可能有多個),並且當您的對象死亡時,如果它們需要採取一些操作,則仍不會通知客戶端 。

+0

嗨,詹姆斯,我已經實現了一個類似的容器,在調用像「objectDeleting」函數之類的函數之後,有效地清除了所有引用/指針。這實際上只是觀察者模式。我開始認爲這對我的經理人來說也不是必要的。 – Shane

0

如果您碰巧正在使用QT,QPointer基本上是指向QObject的弱指針。它將自身連接到指向值中的「我剛被銷燬」事件,並根據需要自動使其自動失效。不過,如果你還沒有跳過QT的圈套,那麼這是一個非常重要的圖書館,可以用來追蹤錯誤追蹤。

+0

謝謝丹尼斯,我沒有使用QT,但無論如何感謝。 – Shane