将原始指针放置并推入智能指针矢量后,它们是否会自动转换为智能指针?

时间:2019-09-06 22:12:01

标签: c++ pointers vector

我偶然发现了这样的代码:

std::vector<std::unique_ptr<Fruit>> fruits;
fruits.emplace_back(new Fruit);

from here

因此,在代码中,我们有一个原始指针(new会产生一个原始指针,对吗?),将其推入唯一指针的向量中。和代码的作品!但为什么?

因为它不能编译:

std::unique_ptr<Fruit> f = new Fruit();

为了方便起见,这是不是有点不可思议?

此外,这种方法代替显式fruits.emplace_back(std::make_unique<Fruit>())可能会遇到什么陷阱?我读过make_unique是创建唯一指针的首选方法。

2 个答案:

答案 0 :(得分:5)

  

代码有效!但为什么?

vector::emplace_back接受参数列表,然后将其转发到它创建的元素的构造函数。

unique_ptr<Fruit>::unique_ptr(Fruit*)是一个构造函数,它拥有传递的裸指针的所有权。

  

此外,此方法代替[{make_unique]的可能陷阱是什么

最大的陷阱是emplace_back可能会引发异常,在这种情况下,还没有成功创建unique_ptr。在这种情况下,传递给emplace_back()的分配对象将被泄漏。因此,最好传递unique_ptr而不是裸露的指针,这样原始指针始终由某人拥有。

关于使用new而不是std::make_unique()的次要要点:它使程序处于“不平衡”状态,从而使您无法使用古老的经验法则“ delete与您new一样多的指针”。在这种情况下,您有一个正确的程序,其中new多于delete。这是否是一个个人问题。

答案 1 :(得分:3)

std::unique_ptr<Fruit> f = new Fruit();

不起作用,但

std::unique_ptr<Fruit> f{new Fruit()};

有效。第一个不起作用,因为在语法上,它使用copy initialization。复制初始化对于std::unique_ptr不起作用,因为接受指针作为参数的构造函数是explicit

fruits.emplace_back(new Fruit);

之所以起作用,是因为上面使用了构造函数。