2011-11-19 125 views
9

什麼是在類層次結構中的幾個類之間共享對象實例的好方法?我有以下情況:在類之間共享對象的好方法是什麼?

class texture_manager; 

class world { 
    ... 
    std::vector<object> objects_; 
    skybox skybox_; 
} 

我目前實施texture_manager作爲一個單身,和客戶端調用它的實例化方法從代碼的任何地方。 texture_manager需要由objects在objects_向量中使用,由skybox_使用,並且可能由其他類別使用,其可能也可能不屬於world類別的一部分。 由於我試圖限制在我的代碼中使用singleton,你建議使用這種方法的替代方法嗎?想到的一個解決方案是將texture_manager引用作爲參數傳遞給需要訪問它的所有類的構造函數。謝謝。

+1

爲什麼不直接聲明你的texture_manager的全局實例?如果處理正確,全局並不是邪惡的。而且它們在線程化環境中的危險性不及任何其他實例傳遞給多個客戶端...... – Mordachai

回答

10

該問題的一般答案是使用::std::shared_ptr。或者如果你沒有那個,::std::tr1::shared_ptr,或者如果你沒有那個,::boost::shared_ptr

你的具體情況,我建議的幾種不同的方法之一:

  1. 一種可能性是,當然,shared_ptr的方法。你基本上把你的指針傳給每個需要這個對象的人,當它們不再需要它時,它會自動銷燬。雖然如果你的紋理管理器最終會指向指向它的對象的指針,那麼你正在創建一個引用循環,並且這必須非常仔細地處理。

  2. 另一種可能性就是將其聲明爲main中的局部變量,並將其作爲指針或引用傳遞給需要它的所有人。在你的程序完成之前,它不會消失,你不必擔心管理生命週期。在這種情況下,裸指針或引用就好了。

  3. 第三種可能性是類似單身人士那種模糊的可接受用法之一。這值得詳細解釋。

你做一個單身人士只是工作是分發有用的指針。它具有的一個關鍵特性是能夠告訴它將指針指向什麼東西。這有點像全球可配置的工廠。

這使您可以擺脫一般單身人士創造的巨大測試問題。只要告訴它在需要測試時就發出一個指向存根對象的指針。

它也允許你逃離訪問控制/安全問題(是的,它們也會產生安全問題),單身人士代表出於同樣的原因。您可以暫時告訴它傳遞一個指向一個對象的指針,該對象不允許訪問您即將執行的代碼段不需要訪問的內容。這個想法通常被稱爲最低權力原則。

使用此功能的主要原因是,它可以節省您找出誰需要您的指針並將其交給他們的問題。這也是不使用它的主要原因,認爲通過對你有好處。你還介紹了這樣一種可能性,即由於你沒有預料到的控制流,兩個預期會得到與紋理管理器相同指針的事物實際上會獲得指向不同紋理管理器的指針,這基本上是導致你的粗糙思維的結果首先使用Singleton。最後,單身人士是如此可怕,即使這種更溫和的使用他們也會讓我發癢。


個人而言,你的情況,我建議的方法#2,只是main創建它在堆棧上,並傳遞一個指針,無論它的需要。它會讓你更仔細地考慮你的程序結構,而這種對象應該可以適用於整個程序的整個生命週期。

+2

我認爲在這裏使用某種共享指針只是一種圍繞棘手(但重要)討論誰實際擁有'texture_manager'對象。一旦沒有人再參考它,它是否真的會被破壞? –

+1

我想過這個,但是將一個shared_ptr傳遞給類層次結構看起來很麻煩,我希望找到一個替代解決方案。或者這不是你想到的? –

+0

@FrerichRaabe:是的,我只是把它作爲'標準建議'的第一次剪輯。這就是我立即想到的問題。但我更深入地分析了它,並更新了我的答案。 – Omnifarious