使用unique_ptr作为我自己的移动构造函数的替代方法是一种好习惯吗?

我正在使用 C++ 制作纸牌游戏。它类似于纸牌,即有不同的堆栈和堆,卡片从一个移动到另一个。

std::vector用于各种桩,但不是std::vector<Card>,我使用std::vector<std::unique_ptr<Card>>. 我这样做的理由是:

  1. 它确保所有权责任与vector它当前所处的位置有关。
  2. 它确保我在堆叠和堆叠之间转移时不会意外地拥有超过 1 张同一张卡的副本,即强制我使用std::move.
  3. 我不必为Card.

这是一种合理的使用方式unique_ptr吗?

编辑:忘了提,有Card从基类派生的不同类型的s。我是一个初学者,不想在所有级别上使用不同的复制和移动构造函数。

回答

  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;
};

请注意,这种设计意味着卡片必须具有某种“空”状态,即移动后它们将被保留。这对应于堆栈中有一个空指针,这就是从唯一指针移动时的情况。

我不相信这一定比允许复制并将责任留给类的用户以遵循游戏规则更好。

这是使用 unique_ptr 的合理方法吗?

单独防止复制不是使用唯一指针的合理理由。

我建议尝试一种不同的设计:不是将卡片存储在向量中,而是用链表表示卡片堆栈。要从堆栈移动到另一个,请提取节点并拼接到另一个列表中。这样卡片就可以是不可变的,不需要代表“空”卡片,而且你不会得到重复。


我忘了提到从基类派生的不同类型的卡片

您不能将派生类实例存储在包含基类对象的向量中。存储派生实例一个std::vector<std::unique_ptr<Card>>合理的用例,因为指针可以指向派生实例的基类子对象。

请注意,动态多态性不一定是纸牌游戏的最佳解决方案。


以上是使用unique_ptr作为我自己的移动构造函数的替代方法是一种好习惯吗?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>