c++的 shared_ptr 大家用的多吗 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
everlost
V2EX    C++

c++的 shared_ptr 大家用的多吗

  •  
  •   everlost 2019-12-17 16:48:19 +08:00 7042 次点击
    这是一个创建于 2127 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

    里面有介绍了三种智能指针以及裸指针的使用场景
    qieqie
        12
    qieqie  
       2019-12-17 18:53:02 +08:00
    c++11 只有 make shared 没有 make unique(c++14 才加)也是挺奇怪的
    yujincheng08
        13
    yujincheng08  
       2019-12-17 19:20:20 +08:00
    @qieqie 其实是忘了加上去了
    nightwitch
        14
    nightwitch  
       2019-12-17 20:17:19 +08:00   1
    @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
        15
    hehheh  
       2019-12-17 21:44:58 +08:00
    用得很多啊,其实不管是用 unique 还是用 shared,想一下需要用指针的哪些场景,然后也不难理解什么时候需要什么了。
    hehheh
        16
    hehheh  
       2019-12-17 21:48:27 +08:00
    @evilhero 对速度有要求的场合。游戏,高频交易,仿真,当然还有各种底层库比如 opencv。其实我一直不明白为什么 python 的一大堆库是用 c 写的而不是 c++,c++效率高多了啊
    hehheh
        17
    hehheh  
       2019-12-17 21:50:48 +08:00   1
    @yujincheng08 能用 shared 写循环导致内存泄露的。。。这个人估计根本不适合写 c++吧。。。
    icylogic
        18
    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
        19
    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"
        20
    yujincheng08  
       2019-12-17 22:21:52 +08:00
    @nightwitch 我说的效率就是那个原子增减操作。不频繁拷贝析构就好。
    yujincheng08
        21
    yujincheng08  
       2019-12-17 22:23:06 +08:00
    @hehheh 但问题就是很多人无脑上 shared_ptr,以为万能,最后内存泄漏。知道有循环引用问题的也就知道用 unique_ptr 了。
    dbow
        22
    dbow  
       2019-12-17 22:39:57 +08:00
    unique_ptr 用的最多,ownership 确定, 随意写也不容易产生泄露。
    5G
        23
    5G  
       2019-12-17 22:52:37 +08:00
    @evilhero #3 你玩股票么?玩的话就接触了 C++的应用场景。
    hehheh
        24
    hehheh  
       2019-12-17 23:01:11 +08:00
    @icylogic 点开以后看到了 make_unique,然后看了看公司电脑的 vs 2010,留下了默默的泪水
    wbing
        25
    wbing  
       2019-12-17 23:13:28 +08:00 via iPhone
    用啊,领导强烈要求项目中不要出现裸指针,所以都用这些,不过 unique_ptr 用的相对多点。
    shiltian
        26
    shiltian  
       2019-12-18 06:46:39 +08:00 via iPhone
    为啥大家都说用 unique 比较多难道没有那种场景,比如多个 memory object 指向同一个 memory buffer 吗?
    yksoft1test
        27
    yksoft1test  
       2019-12-18 08:14:49 +08:00
    表示自己的项目都是 --std=gnu++98 免除这类东西的烦恼
    paoqi2048
        28
    paoqi2048  
       2019-12-18 10:33:23 +08:00
    大部分情况下 unique_ptr 就够了
    ivvei
        29
    ivvei  
       2019-12-18 10:48:51 +08:00
    不多。用的编译器太老,不支持……
    everlost
        30
    everlost  
    OP
       2019-12-18 14:46:51 +08:00
    @cyhone 看完了,写得很棒.
    iclodqp
        31
    iclodqp  
       2022-11-16 20:05:20 +08:00
    unique_ptr 基本能用就用,shared_ptr 必须要用就用。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2760 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 15:08 PVG 23:08 LAX 08:08 JFK 11:08
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86