2015-11-21 72 views
0

我已經團結了好一會兒,回來做一些C++使用Visual Studio 2015年我碰到這個類定義的std ::的unique_ptr試圖引用刪除的功能

class A 
{ 
public: 
    A(); 
    virtual ~A(); 
    A(const A&) = delete; 
    A& operator=(const A&) = delete; 

private: 
    … 
} 

這個類來動態分配如下所示:

ObjPtr obj = ObjPtr(new A()); 

其中ObjPtr是一種類型的定義,並且看起來像:

typedef std::unique_ptr<A> objPtr; 

並使用使用std::move添加這些創建的對象。有一點,我需要遍歷對象列表,如果我找到滿足我的條件的東西,請保留一份。

ObjPtr keep; 

for(auto& object : GetObjectList()) 
{ 
    if(/*check if its the object I want*/) 
    { 
    keep = object; 
    } 
} 

其中GetObjectList返回const std::vector<ObjPtr>&

但是我收到了「嘗試引用已刪除的函數」。我做了一些谷歌搜索,並試圖刪除= delete部分,甚至評論了2條線。我甚至試圖做

ObjPtr keep = std::move(object); 

但我仍然收到刪除的函數錯誤。任何人都可以看到我做錯了什麼或指向我可以幫助一些資源?

+2

'ObjectList'的類型是什麼? – vsoftco

+0

@vsoftco更新了我的文章! – dwnenr

+1

你確定'ObjectList'不是'const'嗎? –

回答

4

A std::unique_ptr無法複製。即使託管對象可以(但你的不能))。

你有一對夫婦在這裏的替代品(所有不同的效果):

  • 變化keep到非擁有原始指針類型(又名A *),並使用keep = object.get();。這是安全的,只有當你知道你不會使用比ObjectList更長的keep(或者更準確地說,你接收的地址的對象)存在。

  • std::unique_ptr移出容器,即使用keep = std::move(object);。當然,現在你在ObjectList中有差距。 (我知道你已經編輯你的問題說ObjectListconst這意味着你不能修改,因此無法移動的物體出來。)

  • 改變,如果你想共享所有權語義的ObjPtrstd::shared_ptr<A>類型。

  • 如果你絕對要對象的副本,你可以添加一個virtual成員函數A是多態克隆的對象。

    class A 
    { 
    public: 
        virtual std::unique_ptr<A> clone() = 0; 
        … 
    }; 
    

    然後您實現從A衍生每一片葉子class該功能。在你的循環中,你使用keep = object->clone();。爲此,您可能希望製作複製構造函數protected但不要delete它。

    請勿使用keep = std::make_unique<A>(*object);,因爲它不會遵守對象的實際(動態)類型,並始終切片爲A。 (由於您的A不可複製,因此無法正常工作。)

1

是什麼使一個唯一的指針「唯一」是隻能存在一個這樣的指向對象的指針。如果你創建了一個唯一指針的副本,你將擁有兩件東西,每件東西都擁有底層對象。當每一個被銷燬時,該對象將被銷燬,導致雙重刪除。

如果您需要多個所有權,請使用shared_ptr。如果您不需要保留副本的代碼中的所有權,則不要保留副本,而是保留指針或引用。

相關問題