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

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

  •  
  •   cyhone · 2019-10-05 13:18:11 +08:00 · 6041 次点击
    这是一个创建于 1877 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    • 不知道三种智能指针的具体使用场景
    • 无脑只使用 shared_ptr
    • 认为应该禁用 raw pointer(裸指针,即 Widget*这种形式),全部使用智能指针

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

    点击查看原文

    9 条回复    2019-10-15 18:54:33 +08:00
    luolikon
        1
    luolikon  
       2019-10-06 11:49:17 +08:00 via iPhone
    写得不错,但感觉在哪看过
    classyk
        2
    classyk  
       2019-10-06 22:49:28 +08:00
    实际使用中 unique_ptr 基本被忽略。能用 unqiue_ptr 的地方,shared_ptr 性能也够了,实在不行上 weak_ptr
    heiheidewo
        3
    heiheidewo  
       2019-10-06 23:41:00 +08:00
    webrtc 里面几乎全是 unique_ptr,虽然用 shared_ptr 可以替代 unique_ptr,但是 unique_ptr 可以从机制上迫使程序员了解变量的调用流程
    macha
        4
    macha  
       2019-10-07 15:13:29 +08:00
    shared_from_this 还可以解决 bind 类成员函数作为回调函数时,对象被析构的问题。
    cyhone
        6
    cyhone  
    OP
       2019-10-08 19:12:53 +08:00
    @classyk unqiue_ptr 和 shared_ptr 是两种不同的使用场景,用对两种指针会让代码语义更加鲜明,也更加优雅
    wutiantong
        7
    wutiantong  
       2019-10-09 10:34:55 +08:00
    智能指针的正确用法大概就是渐渐认识到它们是冗余的。
    wutiantong
        8
    wutiantong  
       2019-10-09 10:36:17 +08:00
    大部分人在智能指针方面最大的错误是滥用。
    FrankHB
        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
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1740 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 16:31 · PVG 00:31 · LAX 08:31 · JFK 11:31
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.