Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;安全对象删除 我写了一个比较大的C++项目,并且有一个对象删除的问题。确切地说,这个项目是一个类似流氓的游戏_C++_Smart Pointers_Delete Operator - Fatal编程技术网

C++;安全对象删除 我写了一个比较大的C++项目,并且有一个对象删除的问题。确切地说,这个项目是一个类似流氓的游戏

C++;安全对象删除 我写了一个比较大的C++项目,并且有一个对象删除的问题。确切地说,这个项目是一个类似流氓的游戏,c++,smart-pointers,delete-operator,C++,Smart Pointers,Delete Operator,我有一个类Npc,它是游戏中的每一个怪物。它们被创建并存储在一个单独的类中,存储,该类负责它们的管理(加载、保存、创建、删除等)。每当怪物死亡时,相应的对象npc必须被删除并完全销毁。删除对象本身不是问题,我只是从存储中调用了一个方法。问题是代码中包含了很多指向这个已经死了的npc的指针,这些指针现在是无效的,尝试使用它们会导致很多问题。例如: 在他死之前,可能有一个他打算执行的动作 他站在一块磁砖上,记录着一个指向他的指针 他可能参与了一些持续的活动,比如抓人 代码中有很多这样的指针,因此几乎

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

  • 在他死之前,可能有一个他打算执行的动作
  • 他站在一块磁砖上,记录着一个指向他的指针
  • 他可能参与了一些持续的活动,比如抓人
  • 代码中有很多这样的指针,因此几乎不可能简单地跟踪它们。我需要的是某种方法来确定一个
    npc
    已经死了,并且该地址上没有存储任何实际对象,这样仍然有这个指针的代码部分就可以对他的死做出适当的反应

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

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

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

    使用弱指针如何?如果您将
    Npc
    存储在
    std::shared_ptr
    (C++11,对于C++03使用
    std::tr1::shared_ptr
    ),则可以创建引用
    shared_ptr
    std::弱_ptr
    (C++11,对于C++03使用
    std::tr1::弱_ptr
    )。当
    shared\u ptr
    实际删除其对象时,所有
    弱\u ptr
    都将能够解决这个问题


    尽管我想知道为什么要删除仍在其他地方使用的
    Npc
    s(例如,仍有操作)。如果您不想让所有其他引用发现您删除了
    Npc
    ,而是希望
    Npc
    在所有引用消失后消失,那么使用
    共享的ptr
    本身(没有
    弱ptr
    )将正常工作。

    根据您提供的信息,我能建议的是你实施这个计划。 如果有代码需要对NPC的死亡做出反应,那么这种模式就是最好的选择。在NPC死亡时,将通知具有指向您的NPC指针引用的代码部分,并使其指向NPC指针的副本为空,并在需要时对NPC的死亡作出反应。在NPC被实际删除之前,死亡通知会发送给所有
    观察员

    有了这个模式,你可以实现“英雄每杀死一个怪物就获得50点生命”这样的机制,而且它很容易扩展


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

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

    每次释放/失效内存时,如何将其设置为
    nullptr
    :PYou已经为你的问题添加了一个答案:使用智能指针。我建议使用std::shared_ptr@SingerOfTheFall,我想你想说的是,每当我做
    删除pnpc我应该做
    pnpc=0。但是,如果程序中的其他地方存储了另一个等于pnpc的指针,它将不会被设置为t0,因此我想这不起作用。我想使用我描述的方法,因为游戏机制就是这样工作的。NPC随时都可能死亡,他不能再采取行动或成为地图的一部分是完全有道理的。我不希望在NPC死后执行任何有意义的代码,确保这一点的一种方法是在他死后立即删除相应的对象。@Saage:我认为如果NPC死了,你会主动删除它的动画,并在删除NPC之前删除它在地图上的存在(或者可能作为其破坏的一部分,尽管这可能是个坏主意),而不是依赖地图和操作列表来实现Npc的消失。通过这种方式,您可以查询操作列表的大小,并确保这实际上是挂起操作的计数。我想我最终会使用
    shared\u ptr
    ,因为它听起来更简单,但观察者模式是一个好主意,我肯定发现它有用,谢谢!