2011-10-31 54 views
1

我正在將(至少)一些代碼轉換爲使用shared_ptr。然而,我遇到了我正在使用的Observer模式的問題。C++觀察者模式:原始指針vs shared_ptr?

我有一個演示者類(Model View Presenter),它實現了觀察者模式,並在某些事件發生時得到通知。我編寫了任何類都可以繼承的通用Subject/Observer類。更新方法看起來是這樣的:

void MyPresenter::Update(Subject *subject) 
{ 
    if(subject == myService_) 
    { 
     DoSomething(); 
    } 
    else if(subject == myOtherService_) 
    { 
     DoSomethingElse(); 
    } 

} 

這工作得很好,直到我轉換myService_(MyPresenter類的成員)到std::shared_ptr。現在表達式(subject == myService_)不再有效。

我最終可能會將所有內容都轉換爲shared_ptr,但在那之前有一個簡單的方法可以讓我使用Observer模式支持raw指針和shared_ptr兩者?理想情況下,我希望觀察者模式對觀察者的指針實現不可知,但也許這是不可能的。我怎樣才能解決這個問題?

UPDATE

如果觀察者圖案Observer接口採取共享指針?還是更好地保持它作爲原始指針?目前我有:

class Subject; 

class Observer 
{ 
public: 
    virtual ~Observer() {} 
    virtual void Update(Subject *subject) = 0; 

protected: 
    Observer() {} 
}; 

回答

1

您可以使用shared_ptr的獲取成員,返回原始指針的shared_ptr包裝:

subject == myService_.get() 

一般來說,我不會建議對所有原始指針盲目地轉換爲shared_ptr秒。你總是必須考慮周圍的對象是否真的擁有指向的對象(並且共享所有權仍然是所有權)。有時一個std::unique_ptr(雖然我不知道tr1已經有這個,否則std::auto_ptr)是一個更好的選擇,如果它是嚴格的所有權或只是一個原始指針,如果它沒有所有權。

但是在接口中,特別是函數參數和返回值,原始指針通常比使用智能指針更好,因此降低了通用性(並且性能也儘管只有微不足道,但對於shared_ptr更是如此)。

注意:我知道這是與現有的答案相同的答案,但我絕望地感到需要反對只是建議在所有地方使用shared_ptr s。

+0

使用Visual Studio 2010,我剛剛發現我可以使用'std :: shared_ptr'而不是'std :: tr1 :: shared_ptr'。 'unique_ptr'也是可用的。 – User

+0

我來自C#,我真的得到關於shared_ptr的混合消息。一方面,人們說,編寫無漏洞的代碼真的很難,特別是當你考慮各種異常情況時,另一方面人們說不要使用它太多。儘管除了性能上的缺點,我還不太清楚使用智能指針的缺點。 – User

+0

@User這會降低靈活性,因爲如果函數參數需要一個參數,您總是必須傳入'shared_ptr',但它不是必需的。在沒有所有權語義(也就是共享所有權)的情況下也使用'shared_ptr'-成員是最好的情況,在概念上是錯誤的,最壞的情況下會導致明顯的錯誤(儘量不要使用智能指針來處理動態分配的對象)。 –

3

爲了使這項工作myService_和主題需要被shared_ptr。否則,您可以嘗試像這樣比較它,如果subject和shared_ptr指向同一個對象。

subject == myService_.get() 

否則,請嘗試更改所有指向shared_ptr的指針。

0

爲什麼不簡單讓模型繼承std::enable_shared_from_this。如果所有權無論如何共享,那麼shared_from_this可以從模型的(可能是虛擬的)方法返回。請注意,這對模型的構造函數有一些限制。