c++ - 在容器中使用智能指针的原因
问题描述
简单写我想问“使用智能指针的好理由是什么?” 例如std::unique_ptr
但是,我并不是在询问使用智能指针而不是常规(哑)指针的原因。我想每个人都知道,或者快速搜索可以找到原因。
我要问的是这两种情况的比较:
给定一个名为MyObject
use的类(或结构)
std:queue<std::unique_ptr<MyObject>>queue;
而不是
std:queue<MyObject> queue;
(可以是任何容器,不一定是队列)
为什么有人应该使用选项 1 而不是 2?
解决方案
这实际上是一个好问题。
我能想到的原因有几个:
多态性仅适用于引用和指针,不适用于值类型。因此,如果您想将派生对象保存在您不能拥有的容器中
std::queue<MyObject>
。一个选项是unique_ptr
,另一个是reference_wrapper
包含的对象从容器外部引用 (*)。根据容器的不同,它包含的元素可以移动,从而使之前对它的引用无效。例如
std::vector::insert
或容器本身的移动。在这种情况下std::unique_ptr<MyObject>
,确保引用是有效的,不管容器对它做了什么(ofc,只要它还unique_ptr
活着)。
在以下示例中,Objects
您可以在队列中添加一堆对象。但是,其中两个对象可能是特殊的,您可以随时访问这两个对象。struct MyObject { MyObject(int); }; struct Objects { std::queue<std::unique_ptr<MyObject>> all_objects_; MyObject* special_object_ = nullptr; MyObject* secondary_special_object_ = nullptr; void AddObject(int i) { all_objects_.emplace(std::make_unique<MyObject>(i)); } void AddSpecialObject(int i) { auto& emplaced = all_objects_.emplace(std::make_unique<MyObject>(i)); special_object_ = emplaced.get(); } void AddSecondarySpecialObject(int i) { auto& emplaced = all_objects_.emplace(std::make_unique<MyObject>(i)); secondary_special_object_ = emplaced.get(); } };
(*) 我在这里使用“reference”的英文含义,而不是 C++ 类型。引用对象的任何方式(例如通过原始指针)
推荐阅读
- c# - 无法加载类型“Newtonsoft.Json.Serialization.CamelCaseNamingStrategy”
- networking - Vagrant:我是否正确设置了三角形拓扑?
- php - 按钮未通向所需位置
- reactjs - 订阅 AWS DynamoDB 中的更改
- javascript - 无法访问 console.log 中显示的 Javascript 对象键值
- r - 如何将前导行中的每一行减去R中的每五行?
- postgresql - PostgreSQL 调用 Group By Limit 操作的所有数据
- jenkins-pipeline - 在电子邮件通知中显示构建持续时间
- scipy - 使用 pip3 安装 scipy 时出错
- java - 如何从 picocli 命令正确启动 micronaut 网络服务器?