我正在用C ++编写一个相对较大的项目,并且在删除对象方面存在问题。该项目,确切地说是一个roguelike游戏。
我有一个班级Npc
,这是游戏中的每个怪物。它们被创建并存储在一个单独的类Storage<Npc>
中,负责管理(加载,保存,创建,删除等)。每当怪物死亡时,必须删除并彻底销毁相应的对象npc
。删除对象本身不是问题,我只是从Storage<NPC>
调用了一个方法。问题是代码包含许多指向已经失效的npc
的指针,这些指针现在无效并且尝试使用它们会导致很多问题。例如:
代码中有很多这样的指针,因此几乎不可能简单地跟踪它们。我需要的是一些方法来确定npc
已经死了,并且没有实际对象存储在该地址上,因此仍然具有此指针的部分代码可以充分地对他的死亡作出反应。
我自己提出了几个想法,但到目前为止,对我来说似乎没有一个好看:
Storage<NPC>
类是否在这样的地址上有一个对象。潜在的问题是在删除对象后,可能会在同一地址上分配另一个对象,这将导致错误。tl; dr version :我需要一个解决方案,告诉我指针是指向一个对象,还是指向一个空闲的内存块,或者指向其他一些对象,对象删除。
答案 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已经死亡,它会减少其引用计数(如果计数现在为零,将导致事后删除)。