std::shared_ptr几点说明

一、原则

使用std::shared_ptr管理具备共享所有权的资源

二、原理

std::shared_ptr是通过引用计数的方式来管理自己的生命周期。
引用计数是通过动态分配一个控制块(参考三、关于控制块的几点说明)来实现的。
我们可以想象与std::shared_ptr<T>对象相关的内存:如图所示。


从这张图中我们还可以看出:

  1. std::shared_ptr的尺寸是裸指针的两倍。
  2. 析构器的型别不是智能指针型别的一部分(区别于std::unique_ptr),这里特别注意,shared_ptr析构器是随着新对象一起指定的,而不是像unique_ptr那样,在定义的时候指定一次就好了。

三、关于控制块的几点说明

  1. 创建时机:
  • std::make_shared总是创建一个控制块
  • 从具备专属所有权的指针(即std::unique_ptr)出发构造一个std::shard_ptr时,会创建一个控制块
  • std::shared_ptr构造函数使用裸指针作为实参来调用时,它会创建一个控制块。
  1. 有一个:从同一个裸指针出发来构造不止一个std::shared_ptr的话,被指涉到的对象将会有多个控制块。多重控制块意味着多重的引用计数,而多重的引用计数意味着该对象会被析构多次!!,错误示例如下:
    auto p = new Widget;
    std::shared_ptr<Widget> sp1(p);
    std::shared_ptr<Widget> sp2(p);

这段代码我们可以习得两个教训。首先,尽可能避免将裸指针传递给一个std::shared_ptr的构造函数。常用的替代手法,是使用std::make_shared。其次,如果必须将一个裸指针传递给std::shared_ptr的构造函数(e.g. 需要自定义析构器),就直接传递new运算符的结果,而非传递一个裸指针变量,即 std::shared_ptr<Widget> sp(new Widget, delFunc);这种形式。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容