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

  • Board类(网格,片段,移动方法等)
  • 枚举的类型为Colour(BLACK/WHITE)和Rank(KING,QUEEN,...,PAWN)


  • 一个Piece结构,用于对颜色和等级(黑金,...,白爪)进行分组。

  • 我现在正在决定如何在板上代表一个正方形的内容(网格)。正方形必须包含Piece(BLACK KING)或不包含任何内容。考虑的选项:
  • 创建一个包含两个数据成员struct Square{bool occupied ; Piece piece;}(可能扩展了Piece类)。
    我的反对意见:解决方案似乎太过沉重,如果正方形不被占用,则piece成员应为空。我觉得这可能会导致某些类方法需要异常(exception),这不是必须的。
  • 扩展了RankColour的枚举以包括一个空选项。
    我的反对:感觉在语义上不雅,hacky和不自然。
  • 查看其他软件包,例如std::optional我的反对:为了编码风格和简洁起见,我想避免使用额外的机制。 std::optional甚至合适吗?
  • 使用NULLnullptr表示一个空方块的状态
    我的反对:再次,似乎很老套。空方块的内容不是NULL,也不是0,不能与数字26相提并论,而应该是一个全新的常量EMPTY_SQUARE。

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

    最佳答案

    国际象棋棋盘上的正方形可以包含一块,也可以是空的。用更抽象的术语来说,您想拥有一些特定的东西,或者根本不拥有任何东西。 这就是std::optional的用例。 无论如何,您都不能避免额外的机械,因为您需要一些东西来代表一个空的正方形。在2019风格的C++中,可选类型是一种非常简单且惯用的解决方案,尤其是当它来自标准库时。

    关于其他选择:

  • struct Square:我同意您的反对意见,尤其是关于在正方形为空时放入piece成员的问题。简而言之:struct Square是可选元素的幼稚,超简单版本。
  • 扩展枚举:我完全同意。
  • nullptr:有时,空指针可能是“nothing”的适当表示形式。通常,当您的实现始终与指针一起使用并且您不想引入std::optional<T*>时会遇到这个问题,因为ojit_code会引入额外的虚无状态及其歧义性。总的来说,我确实同意尽可能避免使用空指针。
  • 关于c++ - 如何使用无效的 `null`或 `empty`像元素来扩展C++结构/类,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54614400/

    10-11 08:37