C++ 句柄与智能指针。使用什么?

C++ 句柄与智能指针。使用什么?,c++,handle,smart-pointers,C++,Handle,Smart Pointers,我开始开发一个图形引擎,只是为了练习。首先出现的问题之一是使用句柄或智能指针来引用我的类实例 在我看来: 智能指针的优点:根据需求创建,它们没有成为过时指针的问题;缺点:因为它们在链表中,所以搜索指针是一个O(n)操作 处理优点:搜索为O(1),对象重新定位为O(1);缺点:可能会成为过时的指针,创建新句柄会强制系统检查handles表中的第一个空条目 选择哪一个?请解释你的选择 编辑: 在你的评论和回答之后,我想澄清一些观点 我的意思不是说智能指针是一个“由STL链表表示”的链表。我的意思

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

在我看来:

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

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

选择哪一个?请解释你的选择

编辑:

在你的评论和回答之后,我想澄清一些观点

我的意思不是说智能指针是一个“由STL链表表示”的链表。我的意思是,它们以某种方式表现为链表(如果您将一个对象从一个内存块移动到另一个内存块,则需要迭代智能指针的完整列表,以正确更新对该对象的所有引用-可以使用链表来完成)


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

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


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

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

使用智能指针,它们会自行处理。

术语“句柄”是一个宽泛的术语,本质上是指对象的标识符

指针或智能指针属于此定义,因此您需要为选项2选择一个更简洁的术语

             "Handle"
                 |
          /------+-------\
         /       |         \
        /        |           \
    Pointer    Reference    Other Identififer
       |         |             \
  |----+----|   `T&`             \
  |         |                 |---+------|
 `T*`  `shared_ptr<T>`      Text       Number (e.g. HWND in WinAPI)
“句柄”
|
/------+-------\
/       |         \
/        |           \
指针引用其他标识符
|         |             \
|----+----|‘T&`\
|         |                 |---+------|
`T*`shared_ptr`文本编号(例如WinAPI中的HWND)
如果我假设你是指某个固定的、内存抽象的“其他标识符”,那么,当然,你可以使用这个。这里不一定有非此即彼的场景。无论如何,您可能都希望使用智能指针(如果没有其他功能,则用于生命周期管理),并且智能指针不需要位于链接列表中

您可以使用
std::map
将固定的用户定义标识符映射到[可能正在更改的]智能指针


免责声明:这张图是匆忙绘制的,代表了我对术语树的看法,现在它就在我起床半小时后。与其他视图可能存在细微的差异,但它应该给人一个相当可靠的印象。

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

指针或智能指针属于此定义,因此您需要为选项2选择一个更简洁的术语

             "Handle"
                 |
          /------+-------\
         /       |         \
        /        |           \
    Pointer    Reference    Other Identififer
       |         |             \
  |----+----|   `T&`             \
  |         |                 |---+------|
 `T*`  `shared_ptr<T>`      Text       Number (e.g. HWND in WinAPI)
“句柄”
|
/------+-------\
/       |         \
/        |           \
指针引用其他标识符
|         |             \
|----+----|‘T&`\
|         |                 |---+------|
`T*`shared_ptr`文本编号(例如WinAPI中的HWND)
如果我假设你是指某个固定的、内存抽象的“其他标识符”,那么,当然,你可以使用这个。这里不一定有非此即彼的场景。无论如何,您可能都希望使用智能指针(如果没有其他功能,则用于生命周期管理),并且智能指针不需要位于链接列表中

您可以使用
std::map
将固定的用户定义标识符映射到[可能正在更改的]智能指针



免责声明:这张图是匆忙绘制的,代表了我对术语树的看法,现在它就在我起床半小时后。与其他视图可能存在细微差异,但它应该给人一个相当可靠的印象。

您能否详细说明使用“句柄”一词时您的具体想法?此外,“搜索指针”的确切含义是什么,为什么你说智能指针存储在链表中?@davidcm:通常
句柄
表示在第一次调用打开设备或文件等后用作标识符的不透明实体(可能是指针)。不确定,您在这里指的是什么类型的
句柄
。为什么您希望在内存中像这样移动对象?即使在定期压缩堆的GC语言中,您也不会重新排列对象,系统会这样做。根据他的评论(关于压缩内存块),我认为他说的是使用类似的东西,其中句柄是指向“主指针块”中系统控制和更新的指针的指针可以在需要内存时以集中方式进行更新