是否有之間的差:根據堆棧和堆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
用於創建智能指針獲取的同一行上。所以我想知道第一個例子是否有效。
是否有之間的差:根據堆棧和堆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
用於創建智能指針獲取的同一行上。所以我想知道第一個例子是否有效。
第一個示例如果有效,但它更具異常安全性並且正確使用make_shared
。
shared_ptr<Foo> sp = make_shared<Foo>();
在你的第一個例子 - 你分配內存,初始化指針與此內存,創建shared_pointer(shared_ptr
現在擁有的內存),然後按複製到向量)。 在第二個示例中 - 您分配內存,使用此內存初始化參數shared_ptr
c-tor,然後如第一個示例中所示。
是否有差[...]根據堆棧和堆
兩者做出同樣使用堆:一個分配爲Foo
對象,和一個用於共享計數器。 (假設一個典型的實施shared_ptr
)
在第一種情況下,foo
持續,直到編碼塊的端部,而在第二暫時指針僅持續直到聲明的末尾。所以原則上,第二個比第一個少用堆棧;但實際上,兩者都應該被優化爲(或多或少)相同。
更好是
_fooVector.push_back(std::make_shared<Foo>());
,因爲這僅需要使一個單一的堆分配兩者的Foo
對象和共享計數。
所以我想知道如果第一個例子是有效的。
是的,這是有效的 - 你可以用任何合適的指針初始化一個共享指針。這有點更危險,原因有兩個:原始指針可用於誤用,並且可能在將其分配給智能指針之前執行其他操作,從而打開泄漏的可能性。從new
表達式直接初始化修復了第一個危險,但並不總是第二個危險。使用make_shared
修復了這兩個問題。
來自:http://www.cplusplus.com/reference/memory/shared_ptr/shared_ptr/
我們允許的第三個構造函數是: 從指針(3)template <class U> explicit shared_ptr (U* p);
所以,是的,第一個例子是有效的。
在涉及這樣的構造函數的模板之間沒有什麼不同。 –
但參考計數器呢?如果shared_ptr被銷燬,將假定shared_ptr被聲明在小於指針的範圍的範圍內,例如在一個塊中聲明內存將被釋放。 –
@Koushik是的。將調用'shared_ptr'析構函數,引用計數器和指針將被刪除,並且您將在代碼中使用懸空指針。 – ForEveR
是否有一個異常安全的方式來創建一個對象後創建一個共享指針? – clankill3r