繁体   English   中英

在容器中使用智能指针的原因

[英]Reason for using smart pointers with a container

简单写我想问“使用智能指针的好理由是什么?” 对于前std::unique_ptr

但是,我并不是在询问使用智能指针而不是常规(哑)指针的原因。 我想每个人都知道,或者快速搜索可以找到原因。

我要问的是这两种情况的比较:

给定一个名为MyObject的 class (或结构)使用

  1. std:queue<std::unique_ptr<MyObject>>queue;

而不是

  1. 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(); } };

(*) 我在这里使用“参考”的英文含义,而不是 C++ 类型。 引用 object 的任何方式(例如通过原始指针)

用例:您希望将某些内容存储在具有常量索引的std::vector中,同时能够从该向量中删除对象。

如果你使用指针,你可以删除一个指向 object 并设置vector[i] = nullptr ,(并且稍后检查它)这是你在存储对象本身时不能做的事情。 如果您要存储对象,则必须将实例保留在向量中并使用标志bool valid或其他东西,因为如果您要从向量中删除 object,则该对象的索引更改为 -1 后的所有索引。


注意:如对此答案的评论中所述,如果您有权访问 C++17 或更高版本,则可以使用std::optional进行归档。

第一个声明生成一个带有指针元素的容器,第二个声明生成纯对象。

以下是在对象上使用指针的一些好处:

  1. 它们允许您创建动态大小的数据结构。
  2. 它们允许您直接操作 memory(例如在从硬件设备打包或解包数据时。)
  3. 它们允许 object 引用(函数或数据对象)
  4. 它们允许您操作对象(通过 API),而无需了解对象的详细信息(API 除外。)
  5. (原始)指针通常与 CPU 寄存器很好地匹配,这使得通过指针解引用值变得高效。 (C++“智能”指针是更复杂的数据对象。)

此外,多态性被认为是面向对象编程的重要特征之一。 C++中的多态性主要分为两种:

  • 编译时多态性

这种类型的多态性是通过 function 重载或运算符重载来实现的。

  • 运行时多态性

这种类型的多态性是通过 Function 覆盖实现的,如果我们想使用基础 class 来使用这些函数,则必须使用指针而不是对象。

暂无
暂无

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

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