C++安全对象删除



我正在用C++写一个相对较大的项目,并且在删除对象方面遇到了问题。准确地说,这个项目是一个类似Rogue的游戏。

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

  1. 他可能打算在死前执行一个动作。
  2. 他站立的瓷砖记录存储着指向他的指针。
  3. 他可能参与了某些持续的活动,比如摔跤某人。

代码中有很多这样的指针,因此几乎不可能简单地跟踪它们。我需要的是某种方法来确定一个npc已经死了,并且没有存储在该地址上的实际对象,以便仍然具有此指针的代码部分可以充分响应他的死亡。

我自己提出了几个想法,但到目前为止,它们对我来说似乎都不是很好:

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

tl;dr 版本:我需要一个解决方案来告诉我指针是否指向一个对象,或者它指向一个空闲的内存块,或者指向在原始对象删除后分配的其他对象。

根据您提供的信息,我可以建议您实现观察者模式。如果有代码需要对NPC的死亡做出反应,那么这种模式就是要走的路。具有指向您的 NPC 的指针引用的代码部分将在 NPC 死亡时收到通知,并使其指向 NPC 的指针副本无效,并对 NPC 的死亡做出反应。在实际删除 NPC 之前,死亡通知会发送给所有observers

通过这种模式,您可以实现诸如"英雄每杀死一个怪物获得 50 点生命值"之类的机制,并且它很容易扩展。

你也可以使用凯文巴拉德的建议,如果没有代码需要积极反应NPC的死亡,只需要处理NPC死亡的情况,就使用shared_ptr

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

虽然我想知道为什么要删除仍在其他地方使用Npc(例如仍然有操作(的 s。如果不是尝试让所有这些其他引用发现您已经删除了Npc,您只是希望Npc在所有引用消失后死亡,那么单独使用shared_ptr(没有weak_ptr(将正常工作。

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

相关内容

  • 没有找到相关文章

最新更新