2013-11-28 48 views
3

是否有之間的差:根據堆棧和堆shared_ptr的創建對象的創建之後

Foo *foo = new Foo(); 
shared_ptr<Foo> sp(foo); 
_fooVector.push_back(sp); 

shared_ptr<Foo> sp(new Foo()); 
_fooVector.push_back(sp); 

。在所有示例中,我可以找到new用於創建智能指針獲取的同一行上。所以我想知道第一個例子是否有效。

回答

6

第一個示例如果有效,但它更具異常安全性並且正確使用make_shared

shared_ptr<Foo> sp = make_shared<Foo>(); 

在你的第一個例子 - 你分配內存,初始化指針與此內存,創建shared_pointer(shared_ptr現在擁有的內存),然後按複製到向量)。 在第二個示例中 - 您分配內存,使用此內存初始化參數shared_ptr c-tor,然後如第一個示例中所示。

+0

但參考計數器呢?如果shared_ptr被銷燬,將假定shared_ptr被聲明在小於指針的範圍的範圍內,例如在一個塊中聲明內存將被釋放。 –

+1

@Koushik是的。將調用'shared_ptr'析構函數,引用計數器和指針將被刪除,並且您將在代碼中使用懸空指針。 – ForEveR

+0

是否有一個異常安全的方式來創建一個對象後創建一個共享指針? – clankill3r

3

是否有差[...]根據堆棧和堆

兩者做出同樣使用堆:一個分配爲Foo對象,和一個用於共享計數器。 (假設一個典型的實施shared_ptr

在第一種情況下,foo持續,直到編碼塊的端部,而在第二暫時指針僅持續直到聲明的末尾。所以原則上,第二個比第一個少用堆棧;但實際上,兩者都應該被優化爲(或多或少)相同。

更好是

_fooVector.push_back(std::make_shared<Foo>()); 

,因爲這僅需要使一個單一的堆分配兩者的Foo對象和共享計數。

所以我想知道如果第一個例子是有效的。

是的,這是有效的 - 你可以用任何合適的指針初始化一個共享指針。這有點更危險,原因有兩個:原始指針可用於誤用,並且可能在將其分配給智能指針之前執行其他操作,從而打開泄漏的可能性。從new表達式直接初始化修復了第一個危險,但並不總是第二個危險。使用make_shared修復了這兩個問題。