我偶然发现了这样的代码:
std::vector<std::unique_ptr<Fruit>> fruits;
fruits.emplace_back(new Fruit);
因此,在代码中,我们有一个原始指针(new
会产生一个原始指针,对吗?),将其推入唯一指针的向量中。和代码的作品!但为什么?
因为它不能编译:
std::unique_ptr<Fruit> f = new Fruit();
为了方便起见,这是不是有点不可思议?
此外,这种方法代替显式fruits.emplace_back(std::make_unique<Fruit>())
可能会遇到什么陷阱?我读过make_unique
是创建唯一指针的首选方法。
答案 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);
之所以起作用,是因为上面使用了构造函数。