如何使用void`null`或`empty` like元素扩展C++结构/类

Owe*_*wen 5 c++ data-structures

我在学习C++时正在实现一个国际象棋模块.在我已经(部分)实施的模块中:

  • 一个Board类(网格,碎片,移动方法等)
  • 枚举类型Colour(黑色/白色)和Rank(KING,QUEEN,...,PAWN)

  • Piece分组颜色和等级的结构(BLACK KING,...,WHITE PAWN).

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

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

    我的反对意见:解决方案似乎有点过于沉重,如果广场没有被占用,那么该piece成员应该是空的.我觉得它可能导致某些类方法需要例外,这些方法本来是不必要的.

  • 扩展枚举RankColour包含空选项.

    我的反对:感觉语言不优雅,黑客和不自然.

  • 寻找其他类似的包 std::optional

    我的反对意见:对于编码风格和简洁性,我想避免使用额外的机器.会std::optional甚至是合适的?

  • 使用NULLnullptr表示空方格的状态

    我的反对意见:再次,看起来很丑陋.空方块的内容不是NULL,也不是数字0,不应该与数字26相当......但应该是一个新的,新的常量EMPTY_SQUARE.

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

bes*_*esc 4

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

\n\n

关于您的其他选择:

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