使用new运算符

时间:2016-10-10 12:06:07

标签: c++ c++11 shared-ptr

我正在尝试通过以下方式定义std::shared_ptr new运算符:

#include <memory>

struct A {
};

int main() {

  std::shared_ptr<A> ptr = new A();

  return 0;
}

但我得到了以下编译时错误:

  

main.cpp:在函数&#39; int main()&#39;:

     

main.cpp:8:30:错误:转换为&#39; A *&#39;到非标量类型&#st; :: shared_ptr&#39;请求std :: shared_ptr ptr = new A();

无论如何,以下肯定有效:

      std::shared_ptr<A> ptr{new A()};

你们有谁知道为什么会这样吗?

2 个答案:

答案 0 :(得分:6)

tl; dr:它是相关构造函数为explicit的结果。

使用=进行初始化时,可以调用复制初始化。 C ++不允许从原始指针复制初始化shared_ptr,因为它太容易导致从一些任意原始指针到shared_ptr的意外隐式转换。实际上管理它。

通过这种方式,你可以选择&#34;诱捕&#34;指向shared_ptr的原始指针是非常刻意且非常明确的(正如您在第二个示例中所做的那样)。现在,只有在这个初始化者中,你必须记住不要使用你已经在其他地方管理过的指针。

特定行std::shared_ptr<A> ptr = new A()是否有任何危险?不,但您所看到的是各种C ++规则协同工作的结果。

答案 1 :(得分:3)

你可以把你的陈述想象成像这样的2个班轮。

A* a = new A();
std::shared_ptr<A> ptr = a;

虽然在这种情况下,这可能在更复杂的代码中是正确的,但它可能导致潜在的陷阱,因此不允许复制初始化到原始指针。

想象

A* a = new A();
//.....
std::shared_ptr<A> ptr = a;
//.....
std::shared_ptr<A> ptr2 = a; //second ptr holding a... UB

在这里,您将拥有2个共享指针,这些指针包含相同的对象,从而导致出现问题。

为了避免那些“隐式”错误,C ++不允许这种初始化。

虽然你仍然可以使用构造函数,但它更“冗长”并且更难以意外地分配指针。

std::shared_ptr<A> ptr{ new A() };

这看起来更像是构建一个新对象,并且可能不会偶然导致错误分配。

在modern中创建共享指针的首选方式也是

auto ptr = std::make_shared<A>();