繁体   English   中英

使用new运算符定义std :: shared_ptr时出错

[英]error when defining a std::shared_ptr with new operator

我试图用以下方式用new运算符定义std::shared_ptr

#include <memory>

struct A {
};

int main() {

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

  return 0;
}

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

main.cpp:在函数'int main()'中:

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

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

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

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

tl; dr:这是相关构造函数explicit

使用=初始化时,将调用复制初始化。 C ++不允许从原始指针复制初始化shared_ptr ,因为从一些任意原始指针到不实际管理它的shared_ptr的意外隐式转换最终会很容易。

这样,你可以将一个原始指针“捕获”到shared_ptr的唯一方法就是非常谨慎而且非常明确(正如你在第二个例子中所做的那样)。 现在,只有在这个初始化器中,你必须记住不要使用你已经在其他地方管理过的指针。

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

你可以把你的陈述想象成像这样的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() };

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

在现代创建共享指针的首选方法是

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM