简单,高效的弱指针,在取消分配目标内存时设置为NULL

Lef*_*ium 8 c++ pointers dangling-pointer

是否有一个简单,有效的弱/保护指针?我需要多个指向同一对象的指针,当删除对象时,这些指针都会自动设置为NULL.有一个"主"指针始终用于删除对象,但可能有几个其他指针引用同一对象.

以下是一些不太符合我需求的解决方案:

  • QPointer:我没有开发QT应用程序; 我不希望从QObject中包含这个libary/derived.
  • boost :: weak_ptr:访问解除分配的对象时抛出异常.我的情况太贵了:测试弱指针应该是正常的; 当弱指针不再有效时,我打算做一些手动清理. 更新:可以在不抛出异常的情况下测试weak_ptr
  • 低开销弱指针:这非常接近我正在寻找的东西,除了我不喜欢这样的事实"只要你不分配2**sizeof(int)次,这个方案只能保证工作同一个地方."

为什么我需要这些弱/保护指针: 我有一个游戏对象列表的游戏.一些对象依赖于其他对象,例如与游戏实体相关联的调试/统计对象.调试/状态对象显示有关游戏实体的有用信息,但它只在游戏实体存在时才有意义.因此,如果删除了游戏实体,则debug/stats对象应实现此功能并自行删除.(另一个想法是跟踪导弹:它可能会搜索新目标,而不是自行删除.)

我希望将调试/统计逻辑与游戏实体分开.游戏实体不应该知道附加了调试/统计对象.虽然我更喜欢弱/保护指针的答案,但我也欢迎不同的方法来处理我的具体任务.我想我可能必须实现一个跟踪对象生命周期的游戏对象管理器,并使用句柄而不是内存地址的原始指针.

我正在用C++开发.

Mic*_*urr 16

您可以使用该lock()成员boost::weak_ptr来测试(然后使用)该值weak_ptr而不处理异常.


Cra*_*rks 10

这在游戏开发中很常见.通常使用对象句柄系统而不是Boost弱指针,因为我们需要底层查找表是常量内存,因为有时我们需要一些Boost没有的额外信息或保证.

通常的方法是使用指针指针的详细说明.实体由句柄而不是指针引用.句柄是指向实体的大量指针的索引.当实体死亡时,它会将实体表中的指针清空.

struct handle_t
{
   uint32 serialnumber;  // this is a GUID for each entity; it increases 
                         // monotonically over the life of the process
   uint   entityindex;
   inline Entity *Get();
}

struct entityinfo_t
{
   Entity *pEntity;  // an entity's destructor NULLs this out on deletion
   uint32  serialnumber;
}

entityinfo_t g_EntityTable[MAX_ENTITIES];

Entity *handle_t::Get() 
{
  entityinfo_t &info = g_EntityTable[entityIndex];
  if ( serialnumber == info.serialnumber )  
  {
     return info.pEntity;
  }
  else
  {
      return NULL;
  }
}
Run Code Online (Sandbox Code Playgroud)

序列号是必要的,因为数组的大小是恒定的 - 最终,您将需要循环实体表条目,并且您可能会将句柄存储到索引#743,足够长的时间以便删除对象和#743单元格重用于其他东西.如果您只是指向指针列表的指针,那么最终会有一个指向完全不同的对象而不是NULL的句柄.因此,我们为每个实体提供一个全局唯一的编号,并将其存储在句柄中.

当然,您可以使用标准向量或映射或字典或其他类型的数据结构作为实体表,但我们的要求通常用于常量内存,高速缓存一致性和绝对最大性能(因为handle_t :: Get ()每帧调用数千次).