std::shared_ptr几点说明

一、原则

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

二、原理

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


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

  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 sp1(p);
    std::shared_ptr sp2(p);

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

你可能感兴趣的:(std::shared_ptr几点说明)