2012-01-12 84 views
15

我想不出任何情況下當構建對象時有沒有任何理由不使用std :: make_shared?

std::shared_ptr<Object> obj(new Object("foo", 1)); 

將是首選,以

auto obj = std::make_shared<Object>("foo", 1); 

後者總是帶來更好的地方,並減少內存碎片。是否有任何情況,您希望(或被迫)使用第一種形式,除了與返回原始指針的代碼進行交互?

+4

我想,你會考慮從'std :: unique_ptr '轉換爲與原始指針接口?因爲我認爲這是從工廠函數返回的規範類型。其他指針會被認爲是「原始指針」,畢竟在現代C++中佔有一席之地? – 2012-01-12 23:18:06

回答

18

後者總是會導致更好的局部性並減少內存碎片。

不是總是。我們鼓勵實現爲引用計數對象和引用計數使用單個分配,但這不是需要才能這樣做。

爲什麼你不想使用std::make_shared?考慮一下你有一個大的動態分配對象的情況,你想擁有std::shared_ptr,並且你知道這個對象的弱引用可能會超過對這個對象的強引用(也許有很多弱引用並且只有一個或兩個短命的強有力的參考)。

在這種情況下,std::make_shared將是一個糟糕的選擇,假設它分配一個同時擁有對象和引用計數的塊:分配的塊(這很大,記住)不能被銷燬,直到沒有強或對象留下的弱引用。

如果您要自己動態分配對象並將指針傳遞給std::shared_ptr構造函數,則只要沒有強引用,即使仍存在弱引用,對象佔用的內存也會被釋放。

+0

這是一個很好的觀點。現在我想到了,引用計數與對象的合併也可能導致錯誤共享,這可能會影響多線程場景中的性能。 – 2012-01-13 00:21:26

0

如果您構建的對象將在對象的生命週期中共享多個實體,那麼是的,您希望儘可能使用std :: make_shared。有些地方可能無法獲得別人的指針,例如,一個工廠可能會返回一個原始指針或一個你想存儲在shared_ptr中的std :: unique_ptr,從而阻止使用make_shared。

標題中的問題有點不同;有很多理由你可能不想爲你的對象使用shared_ptr。如果生命期實際上由多個對象共享,則只應使用shared_ptr。否則,更喜歡堆棧分配對象或使用unique_ptr。

0

現代IDE具有「查找使用」功能。如果使用std::make_shared構造對象,則當您搜索調用該對象的構造函數的位置時,IDE將不會顯示使用std::make_shared的位置。

相關問題