2011-02-02 63 views
6

好的,我開始使用共享指針並儘可能傳遞共享指針。不再轉換爲原始指針。這工作不錯,但在這種特殊情況下:shared_ptr和這個指針

假設我們有一個類,也就是對另一個階級的觀察者,像這樣:

class MyClass : public IObserver 
    { 
    public: 
     MyClass (std::shared_ptr<SomeOtherClass> otherClass); 
     void DoSomethingImportant(); 
    private: 
     std::shared_ptr<SomeOtherClass> m_otherClass; 
    }; 

該類用於像這樣在我的應用程序:

std::shared_ptr<MyClass> myInstance(new MyClass(otherInstance)); 
... 
myInstance->DoSomethingImportant(); 

MyClass獲取到另一個類的共享指針並將其存儲在其m_otherClass數據成員中。 在DoSomethingImportant方法中,MyClass實例做了很多重要的事情,包括在m_otherClass上註冊自己作爲觀察者,如下所示:

m_otherClass-> registerObserver(this);

的問題是,該registerObserver方法這樣定義:

空隙registerObserver(STD :: shared_ptr的觀察者);

它期望一個共享指針,但'this'是一個原始指針,而不是共享指針。

我看到解決這一三種方式:

  • 找到一招正常指針轉換爲共享指針(見問題convert pointer to shared_ptr),但回答這個問題,只建議複製共享指針,而不是如何將指針實際轉換爲共享指針。
  • 將共享指針傳遞給方法,如下所示:「myInstance-> DoSomethingImportant(myInstance);」這似乎有點愚蠢。
  • 將觀察者部分放入單獨的類中。這看起來有點矯枉過正,可能會讓班級更難理解。

這個問題很明顯,共享指針只是C++的一個附加組件(我認爲在其他語言/環境(如C#(或.Net)和Java)中不存在相同的問題)。

有關如何處理這種情況的其他建議或竅門?

+2

你不能使用`enable_shared_from_this`嗎? (請參閱[從此獲取提升shared_ptr])(http://stackoverflow.com/questions/142391/getting-a-boostshared-ptr-for-this)) – 2011-02-02 08:49:17

+3

誰在調低此問題和所有答案?這真的是一個如此愚蠢的問題嗎? – Patrick 2011-02-02 09:05:24

+0

我有時會懷疑......如果有些人不只是簡單地試圖獲得徽章http://stackoverflow.com/badges/7/critic?userid=147192 – 2011-02-02 09:09:46

回答

8

你需要的可能是enable_shared_from_thisshared_from_this設施。該文檔是here

請注意,您不能使用shared_from_this,直到構造函數完全完成並且該對象已被另一個shared_ptr所有。

struct test : boost::enabled_shared_from_this<test> 
{ 
    test() { 
     // shared_from_this(this); // error, still not owned by another shared_ptr 
    } 
    boost::shared_ptr<test> shared() { 
     return shared_from_this(this); 
    } 
}; 
int main() { 
    test * t = new test; 
    // boost::shared_ptr<test> p = t->shared(); // error, not yet owned by other shared_ptr 
    boost::shared_ptr<test> owner(t); 
    boost::shared_ptr<test> p = t->shared();  // [*] ok, "owner" owns the object 
} 

[*]這部分示例很愚蠢,您可以將所有者複製到p中,而不是調用方法。它只是在test方法內部提出要注意何時可以或不需要調用shared_from_this

0

如何使構造私人和具有靜態構造方法是這樣的:

class MyClass : public IObserver 
    { 
    public: 
     static std::shared_ptr<MyClass> createObserver(std::shared_ptr<SomeOtherClass> otherClass); 
     void DoSomethingImportant(); 
    private: 
     MyClass (std::shared_ptr<SomeOtherClass> otherClass); 
     std::shared_ptr<SomeOtherClass> m_otherClass; 
    }; 

然後,你可以在靜態方法實例乾淨的觀察者,而不必擔心這個指針都沒有。

0


您可以將註冊步驟移至單獨的方法嗎? :

shared_ptr<SomeOtherClass> other(new SomeOtherClass()); 
shared_ptr<MyClass> my(new MyClass()); 
// register myself to the observer 
other->registerObserver(my); 
my->DoSomethingImportant(); 

觀察者模式的一個好的設計可以用的boost ::信號來實現和boost ::綁定 庫。我鼓勵你看看。

最好的問候,
馬辛

3

對於觀察者模式,被觀察對象沒有考慮觀察者的所有權,爲什麼不直接使用原始指針?觀察員的生命週期應該由觀察員自己來控制。

通過使用enable_shared_from_this,您可以爲觀察者及其觀察對象引入循環依賴。這意味着如果不明確刪除,資源將永遠不會被釋放。