簡體   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