2012-04-23 108 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的目的,阅读它,它是很好的解释存在。