c++ - 将 unique_ptr 添加到向量中是否可以接受这种方式?
问题描述
说我有一个盒子。它包含由 制造的事物,Box
并且只有Box
。事物也是不可复制的。
还有一个所有权关系,所以我想用unique_ptr
s. (如果盒子消失了,一切都会随之而来。)
#include <memory>
#include <vector>
class Thing {
friend class Box;
public:
~Thing() {/* delete thing */};
private:
Thing() {/* construct thing */};
Thing(const Thing& other) = delete;
Thing& operator=(Thing&& other) = delete;
};
class Box {
private:
std::vector<std::unique_ptr<Thing> > contents{};
public:
void makeThing() {
contents.push_back(nullptr);
contents.back().reset(new Thing()); // I can live with the 'new' keyword here.
}
};
我的问题是:通过推动 anullptr
然后将其重置为新对象来添加向量是否不好?(除了new
关键字,如果构造函数不抛出,这似乎很好?)
注意:我已经看到了克服私有构造函数和删除复制语义的替代 方法。但是我上面写的有什么危险的错误吗?
注意 2:在这里明确说明,因为它已经吸引了一些人:由于 Thing 构造函数是私有的,std::make_unique
因此无法正常工作。
解决方案
我会使用这个构造:
auto thing = std::unique_ptr<Thing>(new Thing());
contents.push_back(std::move(thing));
因为这更多地描述了您实际想要做的事情。您的Box
对象创建一个Thing
对象,将所有权传递给 a unique_ptr
,然后您将其unique_ptr
移至contents
.
并且不要使用contents.emplace_back(new Thing());
一个理由来确定它可能会泄漏。但是 - 恕我直言 - 更重要的部分是可读性和可维护性,如果你写,contents.emplace_back(new Thing());
那么你需要检查是否contents.emplace_back
真的声称拥有所有权(那contents
真的是类型而std::vector<std::unique_ptr<Thing> >
不是std::vector<Thing *>
,很明显,所有权被移动了。std::move(thing)
thing
unique_ptr
您的解决方案的缺点是,在阅读contents.push_back(nullptr);
时不清楚为什么nullptr
要添加,您需要阅读下一行以了解原因。
推荐阅读
- elasticsearch - 为什么双字段的 Sum 有超过 2 个小数位
- python - Heroku 上的错误请求 400 Django 应用程序
- php - 使用 Laravel 5.6 在同一页面上登录和注册?
- android - 无法使用 Google Play 游戏服务登录
- python - 如何通过条件表达式覆盖系列值?
- django - 如何让 Django 表单同时验证多个字段
- cron - Cron 最后一次执行是在晚上 7 点
- haskell - 如何使用 cabal new-test 流式传输测试结果?
- swift - 创建对象时的 ViewController 类
- arrays - 如何将二维数组转换为集合 laravel?