[英]Reason for using smart pointers with a container
簡單寫我想問“使用智能指針的好理由是什么?” 對於前std::unique_ptr
但是,我並不是在詢問使用智能指針而不是常規(啞)指針的原因。 我想每個人都知道,或者快速搜索可以找到原因。
我要問的是這兩種情況的比較:
給定一個名為MyObject
的 class (或結構)使用
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(); } };
(*) 我在這里使用“參考”的英文含義,而不是 C++ 類型。 引用 object 的任何方式(例如通過原始指針)
用例:您希望將某些內容存儲在具有常量索引的std::vector
中,同時能夠從該向量中刪除對象。
如果你使用指針,你可以刪除一個指向 object 並設置vector[i] = nullptr
,(並且稍后檢查它)這是你在存儲對象本身時不能做的事情。 如果您要存儲對象,則必須將實例保留在向量中並使用標志bool valid
或其他東西,因為如果您要從向量中刪除 object,則該對象的索引更改為 -1 后的所有索引。
注意:如對此答案的評論中所述,如果您有權訪問 C++17 或更高版本,則可以使用std::optional
進行歸檔。
第一個聲明生成一個帶有指針元素的容器,第二個聲明生成純對象。
以下是在對象上使用指針的一些好處:
此外,多態性被認為是面向對象編程的重要特征之一。 C++中的多態性主要分為兩種:
這種類型的多態性是通過 function 重載或運算符重載來實現的。
這種類型的多態性是通過 Function 覆蓋實現的,如果我們想使用基礎 class 來使用這些函數,則必須使用指針而不是對象。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.