我正在设计一个简单的 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.
this0x0的原因可能是什么?
编辑:
我确定一切都已初始化,正如我在每个构造函数中所做的那样,在成员初始化程序(例如Board::Tile::Tile() : _colour (Colours::NONE), _owner (nullptr){})中,其中 NONE 是透明的黑色。
我也不太精通调试器,因为在打印调试值时我并没有太多使用它。