我对析构函数有疑问。我有两个类:Map和Tile。它们看起来像这样:(如果下面的代码片段不够用,我要在此项目中添加带有完整代码的github:https://github.com/TMalicki/PathFinder-algorithms)
class Tile
{
private:
Tile* parent;
...
public:
Tile(sf::Vector2f size = { 50.f ,50.f });
Tile(const Tile& cTile);
Tile& operator=(const Tile& aTile);
~Tile();
...
}
和
class Map
{
private:
vector<Tile*> board;
...
public:
Map(sf::Vector2i numberOfTiles = { 10, 10 }, sf::Vector2f sizeOfTiles = {
50.f, 50.f });
Map(const Map& cMap);
Map& operator=(const Map& aMap);
~Map();
...
}
它们的析构函数看起来像这样:
Tile::~Tile()
{
if (parent != nullptr)
{
delete parent;
parent = nullptr;
}
}
Map::~Map()
{
for (int i = 0; i < board.size(); i++)
{
delete board[i];
board[i] = nullptr;
}
}
代码用于最短路径搜索算法。我必须存储以前的Tile,以便在算法找到完成时可以向后搜索最短路径。如果需要,我可以添加更多代码。总结一下:Map对象具有Tiles的向量。首先,每个图块都没有指向任何对象。但是,如果算法使用的是它,而不是前一个的确切Tile存储位置,以此类推。我知道合适的智能指针可以帮助我,但是我虽然首先学习如何做这也许更困难,但这对我很有帮助。我认为问题在于(我不完全知道为什么)在使用Tiles删除地图矢量时,我不仅删除了确切的Tile,而且以某种方式删除了那个Tile的父级Tile?还有在下一个迭代中,当它应该删除上一个迭代的父对象时,它不能删除,因为它已经被删除了。我认为,如果Tile析构函数中的if语句已经存在,将不会被延迟。但这没有帮助。
并且在调试器模式下,我有这个:
在从调试器模式进行分析的过程中,我开始认为,精确图块的析构函数首先删除父图块,然后才删除他自己。之后,它跳转到Tile析构函数中的parent = nullptr行。但是不知何故,只有子Tile被设置为nullptr。
问题可能是父级不是所有者指针,因此它不应删除父级。
Tile::~Tile() {
if (parent != nullptr) {
delete parent; <----------- here
parent = nullptr;
}
}
否则,当地图删除图块时,它已经被删除。删除代码的这一部分应该可以解决问题。