2011-03-23 61 views
7

已經有幾個關於這個主題的問題,但我仍然不確定該怎麼做:我們的代碼庫在很多地方使用shared_ptr。我不得不承認,我們在寫作時沒有明確界定所有權。傳遞給方法時,我應該將shared_ptr轉換爲weak_ptr嗎?

我們有像

void doSomething(shared_ptr<MyClass> ptr) 
{ 
     //doSomething() is a member function of a class, but usually won't store the ptr 
     ptr->foo(); 
     ... 
} 

一些方法已經發現了第一個(間接)循環依賴我想糾正在我們的設計中的錯誤之後。但我不確定如何。從上面改變方法是否有任何好處

void doSomething(weak_ptr<MyClass> ptr) 
{ 
     shared_ptr<MyClass> ptrShared = ptr.lock(); 
     ptrShared->foo(); 
     ... 
} 

我也很困惑,因爲有些人說(包括谷歌風格指南),首先獲得所有權是很重要的(這可能意味着引入很多weak_ptrs,例如在上面的方法的例子中,但也爲我們有很多成員變量)。其他人說(請參閱下面的鏈接),您應該使用weak_ptr來打破循環依賴關係。然而,檢測它們並不總是很容易,所以我想知道是否真的應該使用shared_ptr,直到遇到問題(並意識到它們),然後修復它們?

感謝您的想法!

+0

Would shared_ptr &ptr be better? – DanDan 2011-03-23 16:01:00

+1

「檢測它們並不容易」 - 然後確實需要在設計過程中添加更多步驟。班級關係圖上的明暗線條,或任何需要的東西。你也可以考慮用原始指針而不是弱指針來破壞循環,對於大多數不對稱關係來說,「所有者」永遠不會在所有「非所有者」之前被破壞。 – 2011-03-23 16:01:44

+1

@DanDan:我不這麼認爲,請參閱http://stackoverflow.com/questions/327573/c-passing-references-to-boostshared-ptr – Philipp 2011-03-23 16:03:29

回答

6

見我們沒有界定清楚的所有權。

您需要清楚地說明誰擁有什麼。沒有其他辦法可以解決這個問題。隨意更換shared_ptrweak_ptr的一些用途不會讓事情變得更好。

+0

好吧,我想這應該不會太難,因爲設計(但還沒有:-))太糟糕了。然而,問題依然存在:我應該只在檢測到圈子(如果還有其他地方)或所有對象/方法沒有所有權的地方引入weak_ptrs嗎? – Philipp 2011-03-23 17:47:29

+1

@Phillip - 如果你看看你給出的例子,在傳遞weak_ptr和shared_ptr之間的行爲沒有區別。要使用weak_ptr,必須先從它創建一個shared_ptr,這與首先傳遞shared_ptr的效果相同。 – Nathanael 2011-03-23 18:46:29

2

有些人是對的:你首先應該清楚地瞭解項目中物體的所有權。

shared_ptrs是共享,即「由社區擁有」。這可能或不可取。因此,我建議定義所有權模型,然後不要濫用shared_ptr語義,並在所有權不應該「共享」更多時使用普通指針。

使用weak_ptrs會進一步掩蓋問題而不是修復它。

4

將上面的設計從shared_ptr更改爲weak_ptr沒有任何好處。獲取所有權不是關於使用weak_ptrs,而是關於管理誰將shared_ptr存儲了很長時間。如果我將shared_ptr傳遞給方法,假設我沒有將該shared_ptr作爲該方法的一部分存儲在對象的字段中,但我沒有更改誰擁有該數據。

根據我的經驗,使用weak_ptr的唯一原因是當你絕對必須有一個指針循環,並且你需要打破這個循環。但首先,您應該考慮是否可以修改設計以消除週期。

我通常不鼓勵混合shared_ptr和raw指針。它不可避免地發生(儘管它可能不應該),原始指針需要傳遞給一個採用該類型的shared_ptr的函數。 weak_ptr可以安全地轉換爲shared_ptr,而原始指針不見了。更糟的是,對shared_ptr不熟悉的開發人員可能會從該原始指針創建一個新的shared_ptr並將其傳遞給該函數,從而導致該函數返回時該指針被刪除。 (我實際上必須修復生產代碼中的這個錯誤,所以是的,它確實發生:))

+0

「_It不可避免地發生_(...)」這個解釋是我在SO(或其他地方)看到的weak_ptr的極少數闡述性理由之一。謝謝。 – curiousguy 2012-07-22 14:35:50

3

聽起來像你有設計問題。 shared_ptr爲特定設計解決方案提供了 一個簡單易用的實現,但它(而不是其他任何)可以替代該設計。直到您 已確定每種類型對象 的實際生命週期應該是什麼時,您都不應該使用shared_ptr。完成 之後,大部分shared_ptr/weak_ptr問題應該消失。

如果已經這樣做了,並確定一些 對象的生存不依賴於其他對象,並且有這依賴 週期,你要確定(在設計 水平,再次)如何以管理這些週期---這很有可能,例如 ,在這些情況下,shared_ptr不是正確的 解決方案,或許多涉及的指針僅用於 導航,並且應該是原始指針。

無論如何,您的問題的答案駐留在設計 的水平。如果你在編碼時不得不問,那麼現在是時候去設計 。

相關問題