簡體   English   中英

使用 unique_ptr 作為我自己的移動構造函數的替代方法是一種好習慣嗎?

[英]Is it good practice to use unique_ptr as an alternative to my own move constructors?

我正在使用 C++ 制作紙牌游戲。 它類似於紙牌,即有不同的堆疊和樁,卡從一個移動到另一個。

我對各種樁使用std::vector ,但不是std::vector<Card> ,而是使用std::vector<std::unique_ptr<Card>> 我這樣做的理由是:

  1. 它確保所有權責任與它當前所在的vector有關。
  2. 它確保我在堆棧和堆棧之間轉移時不會意外擁有超過 1 個同一張卡的副本,即強制我使用std::move
  3. 我不必為Card實現自己的復制和移動構造函數。

這是使用unique_ptr的合理方式嗎?

編輯:忘了提一下,有不同類型的Card源自基礎 class。 我是一個初學者,不想在各個級別使用不同的復制和移動構造函數。

  1. 它確保所有權責任與它當前所在的向量有關。

這對我來說意義不大。 Vector 擁有它的所有元素,因此唯一指針在這方面沒有任何價值。

  1. 它確保我在堆棧和堆棧之間轉移時不會意外擁有超過 1 個同一張卡的副本,即強制我使用 std::move 進行轉移。

如果防止復制有用,那么另一種選擇是使Card不可復制 - 或保持Card可復制並創建不可復制的包裝器。 在某種程度上, std::unique_ptr<Card>可以被視為這樣的包裝器,但它不僅僅是一個包裝器,並且對於該用例來說不必要地低效和復雜。 一個簡單的例子:

struct UniqueCard : Card {
    using Card::Card;

    UniqueCard(UniqueCard&&) = default;
    UniqueCard& operator=(UniqueCard&&) = default;

    UniqueCard(const UniqueCard&) = delete;
    UniqueCard& operator=(const UniqueCard&) = delete;
};

請注意,這種設計意味着卡片必須有一些“空”的 state,它們將在移動后留在里面。 這對應於堆棧中有一個 null 指針,從唯一指針移動時會出現這種情況。

我不相信這一定比只允許復制並將責任留給 class 的用戶遵守游戲規則更好。

這是使用 unique_ptr 的合理方式嗎?

單獨防止復制並不是使用唯一指針的合理理由。

我建議嘗試另一種設計:不是將卡片存儲在向量中,而是用鏈表表示卡片堆棧。 要從堆棧移動到另一個,請提取節點並拼接到另一個列表中。 這樣卡片可以是不可變的,不需要代表“空”卡片,而且你不會得到重復。


我忘了提到有不同類型的卡是從基礎 class 派生的

您不能將派生的 class 實例存儲在包含基本 class 對象的向量中。 存儲派生實例std::vector<std::unique_ptr<Card>>合理的用例,因為指針可以指向派生實例的基本 class 子 object。

請注意,動態多態不一定是紙牌游戲的最佳解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM