C ++安全对象删除

时间:2012-09-12 11:06:48

标签: c++ smart-pointers delete-operator

我正在用C ++编写一个相对较大的项目,并且在删除对象方面存在问题。该项目,确切地说是一个roguelike游戏。

我有一个班级Npc,这是游戏中的每个怪物。它们被创建并存储在一个单独的类Storage<Npc>中,负责管理(加载,保存,创建,删除等)。每当怪物死亡时,必须删除并彻底销毁相应的对象npc。删除对象本身不是问题,我只是从Storage<NPC>调用了一个方法。问题是代码包含许多指向已经失效的npc的指针,这些指针现在无效并且尝试使用它们会导致很多问题。例如:

  1. 他可能会在他去世前打算采取行动。
  2. 他站在那里的瓷砖上有一个指向他的指针。
  3. 他可能参与了一些持续的活动,比如擒抱某人。
  4. 代码中有很多这样的指针,因此几乎不可能简单地跟踪它们。我需要的是一些方法来确定npc已经死了,并且没有实际对象存储在该地址上,因此仍然具有此指针的部分代码可以充分地对他的死亡作出反应。

    我自己提出了几个想法,但到目前为止,对我来说似乎没有一个好看:

    • 我可以问Storage<NPC>类是否在这样的地址上有一个对象。潜在的问题是在删除对象后,可能会在同一地址上分配另一个对象,这将导致错误。
    • 我可以通知所有可能使用无效指针的位置。这是一个坏主意,因为这些地点的数量会随着时间的推移而增加,这样做很麻烦。
    • 我可以实现某些版本的智能指针,但我不确定使用哪一个。

    tl; dr version :我需要一个解决方案,告诉我指针是指向一个对象,还是指向一个空闲的内存块,或者指向其他一些对象,对象删除。

3 个答案:

答案 0 :(得分:3)

根据您提供的信息,我建议您实施Observer Pattern。 如果有代码需要对NPC的死亡作出反应,那么这种模式就是要走的路。在NPC死亡时会通知具有指向NPC指针的代码部分,并将其指向NPC的指针无效,并对NPC的死亡作出反应,但需要。在实际删除NPC之前,死亡通知将发送给所有observers

使用这种模式,你可以实现诸如“Hero为每个被杀死的怪物获得50马力”等机制,并且它很容易扩展。

如果没有代码需要对NPC的死亡做出积极反应,你也可以使用Kevin Ballard建议使用shared_ptr,并且只需要处理NPC死亡的情况。

答案 1 :(得分:2)

使用弱指针怎么样?如果将Npc存储在std::shared_ptr(C ++ 11,使用std::tr1::shared_ptr for C ++ 03)中,则可以创建std::weak_ptr s(C ++ 11)再次,使用std::tr1::weak_ptr来表示引用shared_ptr的C ++ 03)。当shared_ptr实际删除其对象时,所有weak_ptr都能够解决这个问题。

虽然我不得不想知道为什么要删除仍在其他地方使用的Npc(例如仍然有动作)。如果您没有尝试让所有这些其他引用发现您已删除Npc,那么您只需要在所有引用消失后Npc死亡,然后单独使用shared_ptr(与没有weak_ptr)可以正常工作。

答案 2 :(得分:0)

一种选择是在您的班级中包含引用计数。当一些其他物体(例如房间)要拿着指向npc的指针时,房间有责任增加npc的引用计数。现在,不是仅删除死亡的npc,而是将其标记为已死(如果您还没有正确的标志,则通过另一个新数据成员),并且只有在其引用计数为零时才删除。房间对象还有责任定期检查该标志,如果它知道npc已经死亡,它会减少其引用计数(如果计数现在为零,将导致事后删除)。