句柄vs智能指针.用什么

Handles vs Smart pointers. What to use?

本文关键字:什么 指针 智能 vs 句柄      更新时间:2023-10-16

我开始开发一个图形引擎,只是为了练习的目的。出现的第一个问题是使用句柄或智能指针来引用我的类实例。

从我的角度来看:

  • 智能指针优点:根据需求创建,它们没有成为过时指针的问题;缺点:由于它们是在链表中,因此查找指针是一个O(n)操作。

  • 处理优点:搜索为O(1),对象重新定位为O(1);缺点:可能成为过时的指针,创建一个新的句柄会强制系统检查句柄表中的第一个NULL条目。

选择哪一个?请说明您的选择。

编辑:

在你们的评论和回答之后,我想澄清一些问题。

我并不是说智能指针是一个"用STL链表表示"的链表。我的意思是它们的行为,在某种程度上就像一个链表(如果你把一个对象从一个内存块移动到另一个内存块,你需要迭代智能指针的完整列表来正确地更新对这个对象的所有引用——这可以用链表来完成——)。

我并不是说句柄完全是不透明的指针或指向实现模型的指针。我的意思是有一个全局句柄表(指针数组),所以当我请求一个对象时,我得到一个可解引用的实例,其中包含这个表中的索引,在这个表中可以找到指向对象的实际指针。因此,如果我将对象从一个块移动到另一个块,只需更新句柄表中的指针条目,所有指针就会同时自动更新。

这两种定义都不符合通常使用的定义。智能指针根本不在链表中。通常,您使用观察者模式来保留一个指向对象的原始指针向量,如果需要迭代它们或其他东西,这些对象仍然存在。你所描述的句柄基本上只用于二进制兼容性原因,而不会在进程内使用。

使用智能指针,它们会照顾好自己的

术语"句柄"是一个广义术语,本质上是指对象的标识符。

指针或智能指针属于这个定义,所以你需要为选项2选择一个更简洁的术语。

             "Handle"
                 |
          /------+-------
         /       |         
        /        |           
    Pointer    Reference    Other Identififer
       |         |             
  |----+----|   `T&`             
  |         |                 |---+------|
 `T*`  `shared_ptr<T>`      Text       Number (e.g. HWND in WinAPI)

如果我假设你指的是一些固定的,内存抽象的"其他标识符",那么,当然,你可以使用这个。这里没有非此即彼的情况。你可能无论如何都想使用智能指针(用于生命周期管理),而且智能指针不需要出现在链表中。

你可以有一个std::map<your_identifier_type, std::shared_ptr<T> >来映射你的固定的,用户定义的标识符到一个[可能改变的]智能指针。


免责声明:这个图表是我匆忙绘制的,它代表了我起床半小时后对术语树的看法。可能与其他观点有细微的出入,但它应该给人一种相当可靠的印象。

句柄的最大缺点是,与指针不同,它们需要额外的上下文来唯一地标识对象。例如,如果handle是一个数组的索引,则需要一个指向该数组的指针来访问该对象。如果数组是动态的,并且基指针可能会改变,则会进一步复杂化。因此,必须使用隐式的global/thread_local上下文,或者使用某种(基数,偏移量)脂肪指针,这可能很难传递给api,期望只是一个指针(例如回调)。

相关文章: