句柄vs智能指针.用什么
Handles vs Smart pointers. What to use?
我开始开发一个图形引擎,只是为了练习的目的。出现的第一个问题是使用句柄或智能指针来引用我的类实例。
从我的角度来看:
-
智能指针优点:根据需求创建,它们没有成为过时指针的问题;缺点:由于它们是在链表中,因此查找指针是一个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,期望只是一个指针(例如回调)。
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 初始化或分配空字符串文字到指向 C 中的 char 的指针或指向 C++ 中 const char 的指针的原因是什么
- int数据类型的指针指向的是什么,如果是一个类的私有数据成员,我们创建了该类的两个对象?
- 使用基类指针调用基类的值构造函数的语法是什么?
- 将指针分配给另一个指针时会发生什么情况?
- 当该数组的索引中没有元素时,指针指向什么?
- C++:Lambda 函数指针转换的用例是什么?
- C++关于指针和使用函数将它们启动到堆的行为究竟是什么?
- 这个失败的测试是将零添加到空指针未定义的行为、编译器错误还是其他什么?
- 使用共享指针时,从共享指针本身释放内存的机制是什么
- 空指针常量 (nullptr)、空指针值和空成员指针值之间有什么区别?
- 什么更好?返回对象指针列表?或返回指向对象列表的指针?
- 什么是更好的做法?通过指针或标识符传递类成员?
- 如果我在 const 函数上使用指针,我可以返回什么?
- 为什么此指针值不能转换为整数的规则是什么?
- 在自定义 std::vector-like 容器中处理指针和非指针模板类型的最佳方法是什么?
- 在什么情况下,需要共享智能指针而无法使用唯一指针?
- 以下与指针相关的代码的输出是什么?
- 指向数组基址的指针而不是指向第一个元素的指针有什么优点?
- C++:在向量中插入什么 - 指针或引用,矢量何时复制它的元素?