如何使用空的"null"或"空"元素扩展C++结构/类
How to extend a C++ structure/class with a void `null` or `empty` like element
我在学习C++时正在实现一个国际象棋模块。 在模块中,我(部分)实现了:
Board
类(网格、片段、移动方法等)- 枚举类型
Colour
(黑/白)和Rank
(国王、王后、...、典当)
和
一种Piece
结构,对颜色和等级进行分组(黑王,...,白色棋子)。
我现在正在决定如何在棋盘(网格)上表示正方形的内容。正方形必须包含Piece
(黑王),或者什么都不包含。考虑的选项:
创建一个包含两个数据成员
{bool occupied ; Piece piece;}
的struct Square
(可能扩展Piece
类)。我的反对意见:解决方案似乎有点太重了,如果广场没有被占用,那么
piece
成员应该是空的。我觉得这可能会导致某些类方法需要异常,这应该是不必要的。扩展
Rank
或Colour
的枚举以包含空选项。我的反对意见:感觉语义上不优雅,笨拙和不自然。
查看其他软件包,例如
std::optional
我的反对意见:为了编码风格和简单性,我想避免使用额外的机器。
std::optional
甚至合适吗?使用
NULL
或nullptr
表示空正方形的状态我的反对意见:再次,似乎很笨拙。空方块的内容不是
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
和类,这些类将实现Pawn
、Knight
、Bishop
、Rook
、Queen
和King
的行为。
NullPiece
将实现相同的行为,但不执行任何操作。
这样,板上的每个Square
都可以有一块。
- 'char (*RtlpNumberOf(T (&)[N]))[N]':无法从"char *"
- Arduino IDE 错误 - 无法找到数字文字运算符"运算符""f900ff"
- "inline"、"constexpr"或"noexcept"
- "非静态数据成员之前需要构造函数" - 我是否使用"boost::variant"
- 我必须安装"libbitcoin-server"才能包含"bitcoin.hpp"
- “并非所有控制路径都返回一个值./&quot“控制可能达到非空隙功能的末端”.验证时循环时
- 如何输出a'&quot在不使用线端的情况下进行文件
- 删除“按任何键” ..&quot.从VS C 控制台应用程序
- 如何检测我何时向可变参数函数传递"std::string"而不是"c_str()"
- '&lt;'''&lt;'''&quot的模板类错误''令牌”
- 错误消息:"jj"的名称查找已更改为ISO"for"范围,(如果您使用"