2016-12-17 90 views
3

我在嘗試解決C++中的指針問題時遇到了一些困難。是否有一個獨特的指針指向共享指針的做法?

比方說,我有一個叫MyClass的課。在這個課堂內部,有一個共享指針指向一些名爲MyResource的外部資源。現在我們還要說在MyClass之內,有一個對象叫做MyObject的幾個實例。 MyObject的每個實例也需要參考MyResource。讓我們假設這個類並沒有做任何東西,除了包含我剛纔提到

class MyClass 
{ 
    shared_ptr<MyResource> m_p_my_resource; 
    MyObject m_my_object1; 
    MyObject m_my_object2; 
    MyObject m_my_object3; 
} 

如何我以前(試圖)來實現此這些成分,我想創建一個共享指針,並給它m_p_my_resource。然後,我會給 MyObject的每個實例。我認爲,無論何時m_p_my_resource更改爲指向新的MyResource,每個MyObjects也會指向新資源。

但是,我意識到我所做的是不正確的。當我改變m_p_my_resource時,這確實會指向一個新的資源。但是,每個MyObject實例仍然會指向原始的MyResource

現在我試圖想想如何實際執行我最初試圖做的方法:能夠更改m_p_my_resource並讓每個實例也指向新資源。

解決此問題的一種方法是更新MyObject的每個實例,只要m_p_my_resource發生更改。我可能需要有一個setResource方法,它會更新m_p_my_resource,然後遍歷每個MyObject的實例。

另一種解決方案是讓MyObject的每個實例都包含指向MyResource的指針。因此,如果每個MyObject都指向一個指向資源的指針而不是資源本身,我可以更改m_p_my_resource,每個對象也可以確定新的資源。

雖然第二種方法可能適用於上面列出的類示例,但對於不包含在類中的MyObject實例並不是很好。因爲如果我簡單地在棧上創建了一個MyObject,我寧願讓它直接指向資源,而不是指向某個指向資源的中間指針...

所以我試圖以確定實施我所描述的最佳方法。我對智能指針還是比較陌生的,我很好奇,如果我想要做的是愚蠢的,或者如果有更好的/明顯的替代解決方案。

+1

第一個解決方案是這樣做的正確的方式OO。它確保適當的封裝,並保持每個數據結構不偶然(假設'MyResource'是不可變的)。 – sbabbi

回答

3

如果MyObject的壽命與MyClass的壽命相同,那麼MyObject的每個實例都可以持有一個引用或指向shared_ptr<...>的指針以實現所需。

class MyClass { 
public: 
    shared_ptr<MyResource> resource; 
    MyObject obj1 { resource }; 
    MyObject obj2 { resource }; 
}; 

class MyObject { 
public: 
    shared_ptr<MyResource>& resource; 
    void foo() { 
     resource->do_something(); // works transparently 
    } 
} 

您可以放心地改變MyClass::resource內容:

void bar(MyClass& myClass) { 
    myClass.resource.reset(new MyResource()); 
    assert(myClass.resource.get() == myClass.ob1.resource.get()); 
    assert(myClass.resource.get() == myClass.ob1.resource.get()); 
} 
+0

你假設了正確的生命週期。這似乎是最優雅的解決方案。我認爲我已經成爲'永遠使用智能指針'而不考慮它們打算用於堆分配/未知壽命對象的事實的犧牲品。 – Izzo

2

雙指針是解決您的問題的正確技術。

但是,我有點困惑,爲什麼你想要一個unique_ptrshared_ptr就像你在標題中說的那樣。你不會在你的問題的任何部分提及unique_ptr,而且看起來你真正想要的是shared_ptr<unique_ptr<MyResource>>,而不是unique_ptr<shared_ptr<MyResource>>

+0

對不起,關於標題,這是一個經典的寫作題目,然後輸入我試圖解決的實際問題,忘記編輯標題。回到你的答案,是不是當你在類中不包含「MyObject」時描述的笨拙?在其他情況下,讓MyObject直接包含對資源的引用會更有意義。思考? – Izzo

+0

正確,那通常是理想的。但是,您要求能夠同時更改所有實例指向的對象,因此您需要雙指針。儘管如此,指針實際上並不需要共享或唯一;你可以使用普通的指針,但是你必須自己管理內存。 – IanPudney