2012-04-23 103 views
5

當初始化一個shared_ptr成員變量:初始化shared_ptr成員變量,新vs make_shared?

// .h 
class Customer 
{ 
public: 
    Customer(); 

private: 
    std::shared_ptr<OtherClass> something_; 
} 

// .cpp 
Customer(): 
    something_(new OtherClass()) 
{ 
} 

Customer(): 
    something_(std::make_shared<OtherClass>()) 
{ 
} 

是對make_shared版本允許嗎?我似乎總是看到第一個版本,這是首選?

+4

香草薩特只是寫上這個GOTW。查看[this](http://herbsutter.com/gotw/_103/)並查看[一個問題](http://lanzkron.wordpress.com/2012/04/22/make_shared-almost-a-silver -bullet /)Herb沒有明確說明。 – 2012-04-24 00:21:04

+0

@RSamuelKlatchko - 你在ansewer使用https://herbsutter.com/2013/05/29/gotw-89-solution-smart-pointers/ – 2017-06-29 07:44:59

回答

11

唯一的時候,make_shared不允許有:

  1. 如果你得到別人並將其存儲在shared_ptr分配的裸指針。與C API接口時通常是這種情況。
  2. 如果要調用構造函數是不公開的(make_shared只能調用公共構造函數)。這可能會發生在工廠函數中,在那裏您要強制用戶從工廠創建對象。

    然而,也有辦法來解決這個問題。有一個私有構造函數,而不是一個公共構造函數。但是使構造函數只能由具有對類的私有訪問權限構造的類型構造。這樣,唯一可以使用該對象類型調用make_shared的人是可以私人訪問該類的人。

所以是的,你可以這樣做。

+0

關於友誼問題提供了一個更新的鏈接,第一個鏈接,沒有任何在特定功能的標準中提及用作朋友?我可以設想一些委託這項工作的實施,以幫助功能... – 2012-04-24 06:53:03

+0

@MatthieuM .:我有點想知道同樣的事情,這就是爲什麼我說「可能」。我在comp.std.C++中詢問過;我們會看到他們對此有何評論。如果沒有,我認爲這可能會使一個體面的缺陷報告。 – 2012-04-24 06:54:50

3

在這種情況下,使用make_shared不僅是允許的,但它是更好地使用它。如果你使用new,它會爲你的Customer分配內存,然後在其他地方爲你的shared_ptr分配內存,存儲強和弱的引用(對於弱指針和共享指針)。如果你使用make_shared,你將只有一個地方在內存中,因此只有一個新的地方。

我不知道,我真的很清楚,這是GotW #103的目的,閱讀它,它是很好的解釋存在。