9

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

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

  • QPointer:我不是在开发 QT 应用程序;我不希望包含来自 QObject 的这个库/派生。
  • boost::weak_ptr访问已释放对象时抛出异常。对我的情况来说太贵了:测试弱指针应该是正常的;当弱指针不再有效时,我计划进行一些手动清理。 update :weak_ptr 可以在不抛出异常的情况下进行测试
  • 低开销弱指针:这与我正在寻找的非常接近,除了我不喜欢这样一个事实“这个方案只有在你不分配 2**sizeof(int) 次的情况下才能保证工作”同一个位置。”

为什么我需要这些弱/受保护的指针: 我有一个带有游戏对象列表的游戏。一些对象依赖于其他对象,例如与游戏实体关联的调试/统计对象。调试/状态对象显示有关游戏实体的有用信息,但它仅在游戏实体存在时才有意义。所以如果游戏实体被删除,调试/统计对象应该意识到这一点并删除自己。(另一个想法是跟踪导弹:它可能会搜索新目标,而不是自我删除。)

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

我正在用 C++ 开发。

4

2 回答 2

17

您可以使用 的lock()成员boost::weak_ptr来测试(然后使用) 的值,而weak_ptr无需处理异常。

于 2009-12-09T19:19:47.770 回答
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;
  }
}

序列号是必需的,因为数组的大小是恒定的——最终,您将需要回收实体表条目,并且您可能会存储一个句柄,例如索引 #743,足够长以至于对象被删除和 #743 单元格被重新用于其他用途。如果您只是有一个指向指针列表的指针,您最终将拥有一个指向完全不同对象的句柄,而不是 NULL。因此,我们给每个实体一个全局唯一的编号,并将其存储在句柄中。

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

于 2009-12-09T20:10:51.557 回答