2014-04-01 65 views
9

我正在嘗試複製自定義類的對象Event。我有一個共同的指向,我已經從劃撥方式取得的對象:如何正確地複製給定其對象shared_ptr的對象

std::shared_ptr<Event> e = std::make_shared<Event>(); 

爲了獲得e一個真正的副本(不只是指針的拷貝)我已經試過:

std::shared_ptr<Event> o = std::make_shared<Event>(*e); 

但我不知道這是正確的做法,因爲它似乎是,如果我刪除e也刪除o ...

順便說一句,我還沒有定義一個拷貝構造函數Event::Event(const Event &orig),但在我的理解這不是因爲編譯器提供了一個默認的拷貝構造函數。事件類只包含變量而沒有其他指針。

+0

看來'e'也刪除了'o'?怎麼會這樣?您可以使用print語句添加析構函數以查看發生了什麼。 – pmr

+0

您可以將日誌記錄到您的Event析構函數中。例如std :: cout。 – cbel

回答

3

std::make_shared僅僅是一個簡單的模板功能創建的對象,將所有參數傳遞給構造函數:

template<class T, class... Args> 
shared_ptr<T> make_shared(Args&&... args) 
{ 
    return shared_ptr<T>(new T(std::forward<Args>(args)...)); 
} 

你的具體情況:

std::shared_ptr<Event> o = std::make_shared<Event>(*e); 

的對象被複制。

如果你的代碼是這樣的:

void foo() { 
    // create new object using default constructor 
    std::shared_ptr<Event> e = std::make_shared<Event>(); 
    // create new object using copy constructor constructor 
    std::shared_ptr<Event> o = std::make_shared<Event>(*e); 
} 

那麼當然這兩個對象被破壞,當他們走出去的範圍。

+0

make_shared()是否必須複製一個新對象?或者在可能的情況下移動物體? –

+0

@TheQuantumPhysicist'foo()'中的第二行使用拷貝構造函數創建一個新對象 - 它不會移動 –

3

你嘗試過什麼應能正常工作,如果動態類型的*eEvent,而不是從Event派生類的一些。 (如果*e實際上是從Event派生的對象,那麼您將創建新的Event(不是派生類型)作爲*e的基類部分的副本,即您將「切片」*e)。

由於您使用make_shared<Event>()創建e你知道,在這種情況下,它確實是一個Event,所以std::make_shared<Event>(*e)應該做一個新的shared_ptr擁有的*e副本。

+0

我遇到了你描述的問題。我如何創建一個從另一個shared_ptr到Base類的Base類的shared_ptr副本,同時保留它實際上是Derived類的事實? –

+0

我現在最好的解決方案是: 'code' std :: shared_ptr newBase; 派生copiedJob = * static_cast (obj.mp_base.get()); \t \t newBase = std :: make_shared (copiedJob); '\ code' –

+0

@IronAttorney使用內聯代碼標記而不是'代碼'。請參閱https://stackoverflow.com/editing-help#comment-formatting –