【发布时间】:2019-11-06 18:11:58
【问题描述】:
我在一些代码中添加了一个析构函数,它似乎提前调用并导致了问题。我添加了一个调试语句来查看它在哪里被调用,这让我更加困惑。我知道管理自己的记忆不是最佳做法,但我想自己尝试一下。
这基本上是我的 GameObject 类:
class GameObject
{
public:
int xCoord = 0, yCoord = 0, prevX, prevY;
int status = 0, weight = -1;
int id = -1;
GameObject(CommandComponent* commands,
PhysicsComponent* physics,
GraphicsComponent* graphics)
: commandComponent(commands),
physicsComponent(physics),
graphicsComponent(graphics)
{};
~GameObject()
{
std::cout << "Destructor called " << id << std::endl;
delete commandComponent;
delete physicsComponent;
delete graphicsComponent;
};
void update(World& world, int command, sf::Time dt)
{
commandComponent->update(*this, world, command);
physicsComponent->update(*this, world);
graphicsComponent->update(*this, dt);
};
void update(World& world, int command)
{
commandComponent->update(*this, world, command);
physicsComponent->update(*this, world);
};
sf::Sprite draw()
{
return *(graphicsComponent->draw());
};
void setCoords(int x, int y)
{
prevX = xCoord;
xCoord = x;
prevY = yCoord;
yCoord = y;
};
void setId(int newId)
{
id = newId;
}
private:
CommandComponent* commandComponent = NULL;
GraphicsComponent* graphicsComponent = NULL;
PhysicsComponent* physicsComponent = NULL;
};
这是 createPlayer 方法:
GameObject* createPlayer(sf::Texture* text)
{
return new GameObject(new PlayerCommandComponent(), new PlayerPhysicsComponent(), new PlayerGraphicsComponent(text));
};
这是我调用的一种方法,根据它是活动对象还是非活动对象,将新对象添加到向量中,我还将它添加到数组中:
void World::addObject(GameObject object, int id, int type){
object.setId(id);
if (type == 0)
{
inactiveObjects.push_back(object);
}
else if (type == 1)
{
activeObjects.push_back(object);
}
}
最后,这是我创建游戏对象并调用上述函数的测试代码,以及我看到从中调用析构函数的位置:
void World::test()
{
// Player
std::cout << "Starting to create id 0\n";
addObject((*createPlayer(&(mTextures.get(Textures::PlayerCharacter)))), 0, 1);
activeObjects.at(0).setCoords(3, 3);
activeObjects.at(0).weight = 10;
std::cout << "Created id 0\n";
// Test Objects
std::cout << "Starting to create id 1\n";
addObject((*createPlayer(&(mTextures.get(Textures::PlayerCharacter)))), 1, 1);
activeObjects.at(1).setCoords(3, 4);
activeObjects.at(1).weight = 7;
std::cout << "Created id 1\n";
addObject((*createPlayer(&(mTextures.get(Textures::PlayerCharacter)))), 2, 1);
activeObjects.at(2).setCoords(5, 4);
activeObjects.at(2).weight = 2;
addObject((*createPlayer(&(mTextures.get(Textures::Enemy)))), 3, 1);
activeObjects.at(3).setCoords(6, 6);
activeObjects.at(3).weight = -1;
addObject((*createPlayer(&(mTextures.get(Textures::Enemy)))), 4, 1);
activeObjects.at(4).setCoords(1, 1);
activeObjects.at(4).weight = 0;
std::cout << "Done Creating Test Objects\n";
我想我的主要问题是如何调用析构函数?我假设它与我在 createPlayer 方法中构造对象的方式有关,也许在我返回它后它超出了范围,但我认为使用 new 关键字可以防止这种情况发生?我在这里感到困惑。
【问题讨论】:
-
将此添加到您的班级:
GameObject(GameObject const&) = delete; -
上述内容的附录:@Eljay 向您展示了如何找到您的课程的意外副本。你可以认为这是对What is the Rule of Three?的介绍
-
考虑使用
nullptr而不是C的NULL。 -
请不要发布文本的截图 - 发布文本本身。此外,您确实需要了解和使用智能指针,而不是手动释放内存。
-
这就是为什么在您知道所有特殊成员函数的作用以及调用它们的时间之前,您不会开始进行手动管理。
标签: c++ destructor