V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
everlost
V2EX  ›  C++

c++的 shared_ptr 大家用的多吗

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

    感觉这个东西有点儿厉害呀,如果在项目里统一的用 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 多了,释放时机不容易掌握。
    tyrantZhao
        9
    tyrantZhao  
       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 用的相对多点。
    tianshilei1992
        26
    tianshilei1992  
       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   ·   我们的愿景   ·   实用小工具   ·   3074 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 14:49 · PVG 22:49 · LAX 07:49 · JFK 10:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.