2013-08-06 29 views
2

我正在試圖找到在代碼中使用shared_ptr和weak_ptr的方法。我有兩個班 - 一班和二班。兩個在一個內部類。第二類的構造函數如下所示接收第一類的weak_ptr並將其存儲以備後用。將此指針作爲weak_ptr傳遞給內部類

Class One 
{  
    Class Two  
    { 
    private: 
     std::weak_ptr<One> m_wptrOne; 

    public: 
     Two(std::weak_ptr<One> wptrOne) 
     { 
      m_wptrOne = wptrOne; 
      /* m_wptr is used later by class Two if not expired and valid ofcourse */ 
     } 
    }; // End Class Two 

    ..... 
    void foo() 
    { 
     std::shared_ptr sptrOne(this); 
     Two obj(sptrOne); 

    .... /* do my work */ 
    } // Program crashes when foo terminates 
}; //End Class One 

我得到一個崩潰時,我的函數foo的回報,因爲我覺得「特徵碼」試圖釋放「這個」指針並認爲這是它唯一的主人。

我該如何解決這個問題?或者,我的程序在架構上不正確?任何建議將不勝感激。

謝謝,
圖莎爾

+0

google'enable_shared_from_this'(C++ 11/Boost for '03)安全地創建了一個指向'this'的共享指針 – mythagel

+0

我曾嘗試過,但沒有奏效。它崩潰在我稱之爲shared_from_this() –

+0

我認爲shared_from_this需要將該對象創建爲共享指針本身。在我的情況下,我在堆棧上創建Object One,而不是作爲共享指針。我不想強制我的圖書館用戶在堆上創建對象作爲共享指針。 –

回答

1

我不想做強制要求我的圖書館用戶在堆上創建一個共享指針的對象。

那麼你的內部類不能要求weak_ptr。使用weak_ptr要求使用shared_ptr;它依靠shared_ptr創建的機制來知道指針何時被銷燬。所以,如果你不希望用戶必須使用shared_ptr,你不能做任何期望該類被包裝在shared_ptr中的任何東西。像從它創建一個weak_ptr

因此,如果您希望用戶無法在堆上創建這些對象,則需要使內部類獨立於weak_ptr

你可以嘗試一些你強制用戶將他們的堆棧對象包裝在使用特殊刪除器的shared_ptr中。但是,這比分配堆更麻煩。

1

的以下爲使用enable_shared_from_thisthis通過弱所有權語義的一個例子。

請注意,無法將弱所有權語義表達爲具有自動存儲持續時間的對象。

您提到的有關shared_from_this的崩潰可能是由於嘗試從未共享的對象獲取shared_ptr而導致的std::bad_weak_ptr類型的異常。

#include <memory> 

class One : public std::enable_shared_from_this<One> 
{  
public: 
    class Two  
    { 
    private: 
     std::weak_ptr<One> m_wptrOne; 

    public: 
     Two(std::weak_ptr<One> wptrOne) 
     { 
      m_wptrOne = wptrOne; 
      /* m_wptr is used later by class Two if not expired and valid ofcourse */ 
     } 
    }; // End Class Two 

    //..... 
    void foo() 
    { 
     std::shared_ptr<One> sptrOne = shared_from_this(); 
     Two obj(sptrOne); 

    //.... /* do my work */ 
    } // Program crashes when foo terminates 
}; //End Class One 


int main() 
{ 
    auto one = std::make_shared<One>(); 
    one->foo(); 
} 
+0

謝謝你,解決方案的作品。但我是一名圖書館作家,我怎麼能假定我的圖書館的用戶將創建對象「一」作爲堆上的共享指針。有沒有其他解決方法,或者我需要編寫一個工廠方法,它將在堆上創建對象,並期望我的用戶使用該工廠方法創建類「One」的對象。 –

+0

「Two」類型的對象是否有可能超過「One」類型的創建者對象?在上面的簡化示例中,它不是,所以看起來最簡單的解決方案是傳遞引用並忽略「One」的分配方式。 – mythagel

+0

完美。得到它了。謝謝。 –

相關問題