c++的 shared_ptr 大家用的多吗

2019-12-17 16:48:19 +08:00
 everlost

感觉这个东西有点儿厉害呀,如果在项目里统一的用 shared _ ptr 来持有和操作 new 出来的对象,基本上不用担心垃圾回收了.

各位平时在项目里用的多吗?有没有什么坑呢?

6573 次点击
所在节点    C++
31 条回复
Fraotisc
2019-12-17 16:51:48 +08:00
用的多,坑在 effective C++上有详细说明
midasfree
2019-12-17 17:18:11 +08:00
现在有现代点的 c++项目不用 shared_ptr 的?
evilhero
2019-12-17 17:29:08 +08:00
借楼问一下,现在 c/c++应用场景有些什么,感觉快没地位了
turi
2019-12-17 17:43:33 +08:00
多啊
坑就是你 shared 我,我 shared 你
避免一下就行了
lhx2008
2019-12-17 17:47:32 +08:00
反正还是朝着高级语言迈进,造各种轮子,性能又提高不了多少
stoneabc
2019-12-17 17:54:15 +08:00
@evilhero
和各种硬件有交互的,游戏,编解码,以及任何需要高性能的地方…
yujincheng08
2019-12-17 17:55:37 +08:00
share 尽量少用,多用的还是 unique。
across
2019-12-17 18:00:24 +08:00
好久没写 C++了···
就是 share 多了,释放时机不容易掌握。
tyrantZhao
2019-12-17 18:01:00 +08:00
如果不是多线程共享资源,还是推荐 unique_ptr,不会带来问题,滥用 shared_ptr 会带来隐藏问题。
yujincheng08
2019-12-17 18:04:12 +08:00
@yujincheng08 滥用 share 容易出现循环引用导致内存泄露。而且 share 本身性能就不算好。还是搞清楚所有权,尽量用 unique 和裸指针,只用真的不止一个所有者权时,才用 share。
cyhone
2019-12-17 18:08:25 +08:00
推荐我的一篇文章:《 C++ 智能指针的正确使用方式》
https://www.cyhone.com/articles/right-way-to-use-cpp-smart-pointer/

里面有介绍了三种智能指针以及裸指针的使用场景
qieqie
2019-12-17 18:53:02 +08:00
c++11 只有 make shared 没有 make unique(c++14 才加)也是挺奇怪的
yujincheng08
2019-12-17 19:20:20 +08:00
@qieqie 其实是忘了加上去了
nightwitch
2019-12-17 20:17:19 +08:00
@yujincheng08 shared_ptr 下层就比 raw ptr 多了个引用计数,不存在什么太大的 overhead,只有构造的时候会稍微慢一点,但也是和 unique_ptr 一个量级的。
根据,http://blog.davidecoppola.com/2016/10/performance-of-raw-pointers-vs-smart-pointers-in-cpp/,连续构造销毁一百万次 shared_ptr,大约比原始指针慢一倍,可以理解,原始指针只需要调用一次 new, shared_ptr 要调用两次 new(变量本身和引用计数器,但是一百万次才 40ms 的开销完全可以忽略不计。

shared_ptr 的坑在一个是循环引用,二是 shared_ptr 自身线程安全(引用计数器是原子操作),但是读写 shared_ptr 管理的对象的时候要加锁,这个坑多线程很容易掉进去。
可以等一波 C++20 的原子智能指针了。
hehheh
2019-12-17 21:44:58 +08:00
用得很多啊,其实不管是用 unique 还是用 shared,想一下需要用指针的哪些场景,然后也不难理解什么时候需要什么了。
hehheh
2019-12-17 21:48:27 +08:00
@evilhero 对速度有要求的场合。游戏,高频交易,仿真,当然还有各种底层库比如 opencv。其实我一直不明白为什么 python 的一大堆库是用 c 写的而不是 c++,c++效率高多了啊
hehheh
2019-12-17 21:50:48 +08:00
@yujincheng08 能用 shared 写循环导致内存泄露的。。。这个人估计根本不适合写 c++吧。。。
icylogic
2019-12-17 22:06:32 +08:00
这种问题很多文章了啊,比在这讨论靠谱多了 ……

https://herbsutter.com/2013/05/29/gotw-89-solution-smart-pointers/
https://herbsutter.com/2013/06/05/gotw-91-solution-smart-pointer-parameters/

而且涉及到真正需要管理 ownership 的地方都是要很小心做封装的,往上一层不涉及 ownership 的地方用 T* T& 传来传去就完事了……

https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#r3-a-raw-pointer-a-t-is-non-owning
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#fcall-parameter-passing
secondwtq
2019-12-17 22:13:21 +08:00
shared_ptr 的最大性能问题是多线程同时操作引用计数
shared_ptr 自身的最大问题是它给你一种可以不用管内存管理问题的假象,让程序员变得过于懒

因为 shared_ptr 的语义是 shared ownership,C++ 要求程序员把 ownership 这坨东西理清楚再写代码,不想折腾的去写 Go 和 JS,shared_ptr 不是合适的解决方案

@icylogic 也就 F2EX 只会瞎吹 ...
yujincheng08
2019-12-17 22:21:52 +08:00
@nightwitch 我说的效率就是那个原子增减操作。不频繁拷贝析构就好。

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

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

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

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

© 2021 V2EX