分配一个新建的 shared_ptr

Assign a newly constructed shared_ptr

我遇到了一个关于shared_ptr的问题,似乎要初始化一个空的shared_ptr,有两种常见的方法引用自std::shared_ptr: reset() vs. assignment

T {
  T(X x, Y y);
  ~T();

}
shared_ptr<T> p;
p.reset(new T(x,y));
p = make_shared<T>(t1) //t1 is a T type object

但是,为什么这行不通?

 p = shared_ptr<T>(new T(x,y));

这只是一种不好的做法还是根本就是错误的?谢谢!

有个回答说make_shared在构造上比new更有效率Is make_shared really more efficient than new?:

std::shared_ptr<Object> p1 = std::make_shared<Object>("foo"); //copy??
std::shared_ptr<Object> p2(new Object("foo")); //conversion?

Is p = shared_ptr<T>(new T()) just a bad practice or it is simply wrong?

您将 NULL 指针与指向默认构造对象的指针混淆了。 "right" 或 "wrong" 都不是;它们只是具有不同的语义并且适用于不同的情况。

However, why this won't work?

p = shared_ptr<T>(new T(x,y));

没关系。它在链接的答案中以这种方式使用。

当其他子表达式可能抛出异常时,将 new 表达式转换为 shared_ptr 是不安全的。由于未指定的评估顺序,可能会发生内存泄漏。但是 new 作为命名变量的初始值设定项是安全的。

std::shared_ptr<Object> p1 = std::make_shared<Object>("foo"); //copy??
std::shared_ptr<Object> p2(new Object("foo")); //conversion?

问题是 shared_ptr 需要堆上的引用计数。 make_shared 能够将共享对象和引用计数合并到一个分配中,而转换需要一个预先存在的对象,因此需要再次调用 new 来计算计数。