我正在设计一个简单的连4游戏。到目前为止,我已经有了4个基本类:
我已经测试了我的
我的测试包括创建两个玩家和一个棋盘。这些都执行正常。接下来,我遍历棋盘的维度,每个方块执行一次。然后我调用:
循环通过
导致崩溃的事件链:
路径变为
这里的第一个比较
我对发生这种情况毫无头绪。我最好的猜测是我错误地使用了智能指针。我之前从未使用过智能指针,但它应该与普通指针非常相似,而且如果指针是
编辑:我确信所有内容都已初始化,因为我在每个构造函数中进行了初始化,在成员初始化器中也进行了初始化(例如:
我对调试器也不是太熟练,因为我很少使用它来打印调试值。
Colour
- 负责表示颜色(RGBA)。包括转换操作。
Player
- 表示游戏中的玩家。每个Player
都有一个Colour
和一个名字。
Board
- 表示游戏棋盘。它包含维度以及具有这些维度的Tile
的2D向量。
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>
。它首先检查瓦片的所有者是否已经设置(即不为nullptr
)。如果没有,则将其中的Player
设置为传入的一个。然后更新瓦片的颜色并返回true
。如果瓦片以前已被占据,则返回false
。
根据调试器,崩溃出现在*_owner = owner;
这一行。进入该行会进入到struct Player
(我声明的Player
类),我认为这是隐式拷贝构造函数(记住该类只有Colour _colour
和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()
只是执行了return _red;
。这就是程序崩溃的地方。调试器显示this
(this->_red
)为0x0。我对发生这种情况毫无头绪。我最好的猜测是我错误地使用了智能指针。我之前从未使用过智能指针,但它应该与普通指针非常相似,而且如果指针是
nullptr
,我认为release
不会产生任何作用。
this
为什么会是0x0的原因可能是什么?编辑:我确信所有内容都已初始化,因为我在每个构造函数中进行了初始化,在成员初始化器中也进行了初始化(例如:
Board::Tile::Tile() : _colour (Colours::NONE), _owner (nullptr){}
),其中NONE是透明黑色。我对调试器也不是太熟练,因为我很少使用它来打印调试值。
Board
中的Tile
类的目标是完全包含它。tile
函数最初是一个const
返回,但我只是为了测试而改变了它。可以从Board
外部访问这些瓷砖,但不能创建新的瓷砖,只能处理已有的瓷砖。当然,Board
通过瓷砖向量提供非const访问(这就是我提供的has-a关系)。简而言之,一个board对象具有2D瓷砖向量。 - chrisowner().colour()
只需要多加一步简短的操作。 - chris