2016-02-10 24 views
2

我需要能夠訪問其在不同的具體類實現返回一個對象。所以我決定使用std::shared_ptr。我想知道在這裏使用std::shared_ptr是否合適,如果不是,請建議我是否應該使用std::weak_ptr。到目前爲止,我一直在使用原始指針,但現在我決定在我的項目中使用智能指針,但我無法決定在這裏使用哪一個。下面的代碼段與我在我的項目中試圖做的類似。與shared_ptr的工作從另一個具體類

#include <iostream> 
#include <memory> 

class data 
{ 
    public: 
    data() 
    { 
     std::cout<<"\n data constructor Called"<<std::endl; 
    } 
    ~data() 
    { 
     std::cout<<"\n data destructor Called"<<std::endl; 
    } 
    int GetData() 
    { 
     return val; 
    } 
    void SetData(int & val) 
    { 
     this->val = val; 
    } 
    private: 
    int val; 
    }; 

    class sample 
    { 
    public: 
    sample(); 
    ~sample(); 
    void GetShared(std::shared_ptr<data> & arg); 
    std::shared_ptr<data> sPtr; 
    }; 

    sample::sample() 
    { 
    sPtr = std::make_shared<data>(); 
    } 

    sample::~sample() 
    { 
    } 

    void sample::GetShared(std::shared_ptr<data> & arg) 
    { 
    arg = sPtr; 
    } 

    int main() 
    { 
     int val = 40; 
     sample obj; 
     { 
      std::shared_ptr<data> temp1; 
      obj.GetShared(temp1); 
      temp1->SetData(val); 
      std::cout<<"\n Data : "<<temp1->GetData()<<std::endl; 
     } // Just to understand whether pointer gets deleted if temp1 goes out of scope. 

     { 
      std::shared_ptr<data> temp2; 
      obj.GetShared(temp2); 
      val = 20; 
      temp2->SetData(val); 
      std::cout<<"\n Data : "<<temp2->GetData()<<std::endl;  
     } 

     return 0; 
    } 

回答

1

shared_ptr的和的weak_ptr之間的區別是,的weak_ptr不增加對象上的引用計數和不阻止該對象被刪除。

這有其優缺點,如果您在獲取指針後執行異步操作並且不確定提供數據的對象是否已被銷燬,那麼您可以使用weak_ptr並檢查是否仍有權訪問該對象。

如果沒有,那麼保持它的簡單和使用的shared_ptr。

4

你會使用shared_pointer分享一些資源的所有權,當你沒有這樣的資源的一個明確的所有者。

在這裏,如果你不知道,如果obj超出範圍temp1temp2data做這將是有益的。然而,在這個例子中清楚的是objdata對象其持有活得比用戶。在這種情況下,你可以返回一個正常的指針,或者是對數據的引用。

使用shared_pointer(或weak_pointer)不買任何東西,除了增加了複雜性。

+0

非常清楚,但(在恢復正常的指針或引用的情況下),如果用戶正在試圖刪除由方法'obj.GetShared(temp1);'返回的指針。在返回的'std :: shared_ptr'上應用'delete'會引發編譯錯誤。我在這裏錯過了什麼,是否仍然推薦使用普通指針? – Panch

+0

@Panch用戶不應該刪除原始指針。 – Galik

+0

@Galik那麼你如何在C++ 11之前正確地返回一個數組?我看到一個指針被用於這個和「用戶」必須刪除數據的類似用例。 –

2

在你的代碼

sample obj; 
    { 
     std::shared_ptr<data> temp1; 
     obj.GetShared(temp1); 
     temp1->SetData(val); 
     std::cout<<"\n Data : "<<temp1->GetData()<<std::endl; 
    } // Just to understand whether pointer gets deleted if temp1 goes out of scope. 

的數據不會被刪除,因爲它指向的東西是由obj舉行,這是還活着。


我認爲答案應該取決於data對象是否可以將其相應的sample對象後生活而死

  • 如果是的話,那麼它應該返回std::shared_ptr
  • 如果不是,那麼它應該返回一個std::weak_ptr
+0

如果包含'data'的'sample'對象被銷燬,'data'對象將被銷燬。另外,假定'sample'對象是活着的,直到exe運行完成它的活動。所以我認爲'std :: shared_ptr'是我的正確選擇。 – Panch

+0

謝謝@henrikgiesel - 讚賞! –

1

你有你需要問自己兩個問題。

1)將來自sample獲取指針調用對象活得比的sample對象?

如果然後sample應該使用std::unique_ptr並返回原始指針參考

2)如果調用對象確實活得比的sample對象,是否介意它之前data對象被銷燬?

如果然後返回,可用於測試是否data對象仍然在使用它之前活着std::weak_ptr

否則返回std::shared_ptr保證data對象的生活,只要調用對象

摘要:

如果調用對象不會活得比的sample對象:

class sample 
{ 
    std::unique_ptr<data> ptr; // UNIQUE (not shared) 

    public: 

    data* GetData() { return ptr.get(); } 
}; 

如果調用對象可以活得比的sample對象,但如果不關心data只要物體存在,物體就會一直存在:

class sample 
{ 
    std::shared_ptr<data> ptr; 

    public: 

    std::weak_ptr<data> GetData() { return ptr; } 
}; 

如果調用對象可以活得比的sample對象,需要data對象保持住得:

class sample 
{ 
    std::shared_ptr<data> ptr; 

    public: 

    std::shared_ptr<data> GetData() { return ptr; } 
}; 
+0

答案很好解釋,它給了我一個關於如何使用C++ 11智能指針的清晰畫面。非常感謝幫助。 – Panch

相關問題