我正在设计一个简单的 Connect 4 游戏。到目前为止,我有 4 个基础类:
Colour
- 负责表示颜色(RGBA)。包括转换运算符。
Player
- 代表游戏的玩家。每个Player
都有一个Colour
和一个名字。
Board
- 代表棋盘。它包含维度,以及Tile
具有这些维度的 s 的二维向量。
Tile
- 内的嵌套类Board
。代表板上的一个空间。每个瓷砖的所有者Tile
都有一个Colour
和一个。std::unique_ptr
所有者以 开头,nullptr
并且可以更改一次为Player
。颜色以透明黑色开始。
我已经测试了我的Colour
课程,它似乎工作正常。我的Player
班级也处于最佳状态。但是,我在Board/Tile
上课时遇到了一些问题。
我的测试包括创建两个玩家和一个棋盘。这些正常执行。接下来,我遍历电路板的尺寸,每个瓷砖一次。然后我打电话
board.tile (j, i).claimBy (p2);
循环遍历带有 的行和带有的i
列j
,这是您期望的打印方式。
tile (j, i)
检索我正在使用的图块。它按预期工作。
导致崩溃的事件链:
claimBy (p2)
设置牌被玩家 2 认领。它的实现如下:
bool Board::Tile::claimBy (const Player &owner)
{
if (!_owner)
{
*_owner = owner;
_colour = owner.colour();
return true;
}
return false;
}
_owner
是我的std::unique_ptr<Player>
。它首先检查之前是否设置了图块的所有者(即 is not nullptr
)。如果不是,它将Player
内部设置为传入的那个。然后它更新瓦片的颜色并返回true
。如果该图块先前已被认领,则返回false
。
在调试器之后,崩溃发生在*_owner = owner;
. 介入将我带到行struct Player
(我的Player
类声明),我认为它是隐式复制构造函数(请记住该类只有 aColour _colour
和 a std::string _name
)。
再次介入会导致我Colour::operator=
(这对于调用复制构造函数是有意义的)。这是定义:
Colour &Colour::operator= (const Colour &rhs)
{
if (*this != rhs)
{
_red = rhs.red();
_green = rhs.green();
_blue = rhs.blue();
_alpha = rhs.alpha();
}
return *this;
}
路径变为*this != rhs
。这只是对 的反向调用operator==
,即:
return red() == rhs.red()
&& green() == rhs.green()
&& blue() == rhs.blue()
&& alpha() == rhs.alpha();
red() == rhs.red()
这里的第一个比较red()
是 just return _red;
。这是程序崩溃的地方。调试器声明this
( this->_red
) 为 0x0。
我不知道为什么会这样。我最好的猜测是我错误地使用了智能指针。我以前从未真正使用过它,但它应该与普通指针非常相似,而且我认为release
如果指针是nullptr
.
this
0x0的原因可能是什么?
编辑:
我确定一切都已初始化,正如我在每个构造函数中所做的那样,在成员初始化程序(例如Board::Tile::Tile() : _colour (Colours::NONE), _owner (nullptr){}
)中,其中 NONE 是透明的黑色。
我也不太精通调试器,因为在打印调试值时我并没有太多使用它。