C++智能指针的正确使用方式

2019-10-05 13:18:11 +08:00
 cyhone

C++11 中推出了三种智能指针,unique_ptr、shared_ptr 和 weak_ptr,同时也将 auto_ptr 置为废弃(deprecated)。

但是在实际的使用过程中,很多人都会有这样的问题:

本文试图理清楚三种智能指针的具体使用场景,并讲解三种智能指针背后的性能消耗。同时也解释了为什么要用 shared_from_this 以及智能指针的函数传参问题。

点击查看原文

6036 次点击
所在节点    C++
9 条回复
luolikon
2019-10-06 11:49:17 +08:00
写得不错,但感觉在哪看过
classyk
2019-10-06 22:49:28 +08:00
实际使用中 unique_ptr 基本被忽略。能用 unqiue_ptr 的地方,shared_ptr 性能也够了,实在不行上 weak_ptr
heiheidewo
2019-10-06 23:41:00 +08:00
webrtc 里面几乎全是 unique_ptr,虽然用 shared_ptr 可以替代 unique_ptr,但是 unique_ptr 可以从机制上迫使程序员了解变量的调用流程
macha
2019-10-07 15:13:29 +08:00
shared_from_this 还可以解决 bind 类成员函数作为回调函数时,对象被析构的问题。
GeruzoniAnsasu
2019-10-07 16:28:51 +08:00
cyhone
2019-10-08 19:12:53 +08:00
@classyk unqiue_ptr 和 shared_ptr 是两种不同的使用场景,用对两种指针会让代码语义更加鲜明,也更加优雅
wutiantong
2019-10-09 10:34:55 +08:00
智能指针的正确用法大概就是渐渐认识到它们是冗余的。
wutiantong
2019-10-09 10:36:17 +08:00
大部分人在智能指针方面最大的错误是滥用。
FrankHB
2019-10-15 18:54:33 +08:00
智能指针不止是 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

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/606429

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX