C++11 中推出了三种智能指针,unique_ptr、shared_ptr 和 weak_ptr,同时也将 auto_ptr 置为废弃(deprecated)。
但是在实际的使用过程中,很多人都会有这样的问题:
本文试图理清楚三种智能指针的具体使用场景,并讲解三种智能指针背后的性能消耗。同时也解释了为什么要用 shared_from_this 以及智能指针的函数传参问题。
1
luolikon 2019-10-06 11:49:17 +08:00 via iPhone
写得不错,但感觉在哪看过
|
2
classyk 2019-10-06 22:49:28 +08:00
实际使用中 unique_ptr 基本被忽略。能用 unqiue_ptr 的地方,shared_ptr 性能也够了,实在不行上 weak_ptr
|
3
heiheidewo 2019-10-06 23:41:00 +08:00
webrtc 里面几乎全是 unique_ptr,虽然用 shared_ptr 可以替代 unique_ptr,但是 unique_ptr 可以从机制上迫使程序员了解变量的调用流程
|
4
macha 2019-10-07 15:13:29 +08:00
shared_from_this 还可以解决 bind 类成员函数作为回调函数时,对象被析构的问题。
|
5
GeruzoniAnsasu 2019-10-07 16:28:51 +08:00
|
6
cyhone OP @classyk unqiue_ptr 和 shared_ptr 是两种不同的使用场景,用对两种指针会让代码语义更加鲜明,也更加优雅
|
7
wutiantong 2019-10-09 10:34:55 +08:00
智能指针的正确用法大概就是渐渐认识到它们是冗余的。
|
8
wutiantong 2019-10-09 10:36:17 +08:00
大部分人在智能指针方面最大的错误是滥用。
|
9
FrankHB 2019-10-15 18:54:33 +08:00 1
智能指针不止是 std 给你的那坨。
没有所有权的指针语义上更清楚的是 observer_ptr (如果不需要 nullable,那直接引用,包括 & 、&& 或者 std::reference_wrapper 或者其它什么类似物)。这种做法唯一的缺陷就是罗嗦,但这是语言设计本来的问题——谁叫内建指针这种责任不明确的垃圾占用了 * 这样的更简洁的语法呢(即便 * 这种语法本来就很不咋地)?注意,如果要求是像样的而不是容易让实现偷懒的设计,原则上混淆使用目的的内建指针就不应该直接在高级语言中提供: https://github.com/FrankHB/pl-docs/blob/master/zh-CN/why-is-pointer-awful.md 。 内建的指针因为兼容包袱永远不可能更清楚,所以和 LZ 的提法相反,就是应该能禁用就禁用,而体现不得不用和可以被其它类型取代时的区别。事实上:根本意义上只有一种情况才必须使用内建的指针——互操作,例如内联汇编需要依赖二进制兼容,或者 new 这种从核心语言特性钦定返回内建指针的情形的变通(本质上,返回内建指针仍然是个目无所有权的糟粕设计,仅仅因为 T* 是内建语法就凌驾于去任意地复用而不是提供特设的 new_ptr<T> 或者干脆直接返回现代意义的 unique_ptr<T> ,这种选择根本没什么逻辑性,而且是个后患无穷的做法;只不过当年 C++ 还没模板也没 move copy-initialization,这种垃圾设计就当历史包袱忍了算了)。使用内建指针根本不能区分不得不用内建指针和允许使用 observer_ptr 的情形,仍然削弱了目的性。 题外话,BS 是反对 observer_ptr 的: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1408r0.pdf 。不过,根本上他的理由站不住脚,一部分就是上面的原因(另一部分问题是关于语言特性历史包袱的理解和 WG21 整体对核心语言设计演进方向控制上的普遍无能)。 有所有权的情形在 unique_ptr 之前首先考虑直接传值。(至少还得清楚没法表达 __restrict 的情形下没事用指针 /引用永远是被坑的。) shared_from_this 有的坑是因为 weak_ptr 被滥用: https://stackoverflow.com/questions/39653239 |