2

我正在用 C++ 编写一个相对较大的项目,并且在删除对象时遇到了问题。该项目,准确地说是一个roguelike游戏。

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

  1. 在他死之前,他可能打算执行一项行动。
  2. 他站立的瓷砖上记录着指向他的指针。
  3. 他可能参与了一些持续的活动,比如与某人搏斗。

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

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

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

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

4

3 回答 3

3

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

使用这种模式,您可以实现诸如“英雄每杀死一个怪物获得 50 生命值”的机制,并且它很容易扩展。

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

于 2012-09-12T11:19:51.430 回答
2

使用弱指针怎么样?如果将 存储Npc在(C ++ std::shared_ptr11,std::tr1::shared_ptr用于 C++03)中,则可以创建引用. 当s实际删除它的对象时,所有的s 都将能够解决这个问题。std::weak_ptrstd::tr1::weak_ptrshared_ptrshared_ptrweak_ptr

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

于 2012-09-12T11:10:49.343 回答
0

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

于 2012-09-12T11:24:20.697 回答