如何使用空的"null"或"空"元素扩展C++结构/类

How to extend a C++ structure/class with a void `null` or `empty` like element

本文关键字:quot C++ 结构 扩展 null 何使用 元素      更新时间:2023-10-16

我在学习C++时正在实现一个国际象棋模块。 在模块中,我(部分)实现了:

  • Board类(网格、片段、移动方法等)
  • 枚举类型Colour(黑/白)和Rank(国王、王后、...、典当)

一种
  • Piece结构,对颜色和等级进行分组(黑王,...,白色棋子)。

我现在正在决定如何在棋盘(网格)上表示正方形的内容。正方形必须包含Piece(黑王),或者什么都不包含。考虑的选项:

  • 创建一个包含两个数据成员{bool occupied ; Piece piece;}struct Square(可能扩展Piece类)。

    我的反对意见:解决方案似乎有点太重了,如果广场没有被占用,那么piece成员应该是空的。我觉得这可能会导致某些类方法需要异常,这应该是不必要的。

  • 扩展RankColour的枚举以包含空选项。

    我的反对意见:感觉语义上不优雅,笨拙和不自然。

  • 查看其他软件包,例如std::optional

    我的反对意见:为了编码风格和简单性,我想避免使用额外的机器。std::optional甚至合适吗?

  • 使用NULLnullptr表示空正方形的状态

    我的反对意见:再次,似乎很笨拙。空方块的内容不是NULL,也不是0的数字,不应该与数字26相提并论...但应该是一个新鲜的、新的常EMPTY_SQUARE。

这些选项似乎都不太合适。是否有一些更优雅的方式来扩展一个类(如Piece)与其他成员(如EMPTY_SQUARE),而这些成员没有原始类的数据成员?(还有其他选择吗?

棋盘上的方块可以包含棋子,也可以是空的。用更抽象的术语来说,你要么想要一些特定的东西,要么什么都没有。这正是std::optional的用例。无论如何,您都无法避免额外的机器,因为您需要一些东西来表示一个空的正方形。在 2019 风格的C++可选类型是一种非常简单且习惯性的解决方案,尤其是当它来自标准库时。

关于您的其他选择:

  • struct Square: 我同意你的反对意见,特别是关于当正方形为空时放入piece成员的问题。简而言之:struct Square是一个幼稚的、超级简单的可选版本。
  • 扩展枚举:我完全同意。
  • nullptr:有时空指针可以是"无"的适当表示。通常,当您的实现无论如何都使用指针并且您不想引入std::optional<T*>时,您会遇到这个问题——这将引入额外的无状态及其歧义。总的来说,我同意尽可能避免空指针。

保留一组非空方块怎么样?

typedef std::map<square,piece,chessboard_order,chessboard_allocator> chess_position;

需要定制分配器,因为可能不超过 64 个正方形。此外,随着游戏的进行,收藏品会缩小,因为碎片被拿走了。

每个人物都有一个位置怎么样?并在板上存储所有数字的列表。

董事会将具有与核实行动规则相关的逻辑。

另一种方法是引入Null_Piece(空对象模式)

然后你需要做的是创建基类Piece和类,这些类将实现PawnKnightBishopRookQueenKing的行为。

NullPiece将实现相同的行为,但不执行任何操作。

这样,板上的每个Square都可以有一块。