目录
三、control block的生成时机
一、std::shared_ptr<T>
shared_ptr的内存模型如下图:
- 比正常纸质大一倍(16byte)
- 由图可以看出,shared_ptr包含了一个指向对象的指针和一个指向控制块的指针。
- 每一个由shared_ptr管理的对象都有一个控制块,它除了包含强引用计数、弱引用计数之外,还包含了自定义删除器的副本和分配器的副本以及其他附加数据(与unique不同)。并且shared_ptr的大小不会受自定义删除器大小的变化而变化。
auto loggingDel=[](Widget* pw){ makeLogEntry(pw); delete pw;}std::unique_ptr<Widget, decltype(loggingDel)> upw(new Widget, loggingDel);
std::shared_ptr<Widget)> spw(new Widget, loggingDel);
二、std::shared_ptr性能问题
- 大小需要是原始指针的两倍
- 引用技术内存必须动态分配
- 引用技术的增减必须是原子操作
三、control block的生成时机
- 使用 std::make_shared
- 向 shared_ptr 的构造函数中传入一个裸指针
- 通过 unique_ptr 构造 shared_ptr
四、std::shared_ptr可能存在的问题
如何解决?
查看 三、control block的生成时机, 调用拷贝构造就不会创建blcok
五、使用this指针作为std::shared_ptr构造函数实参
上面的代码会创建两次 control_blcok ,那有什么解决方法?CRTP
但是下面这两种写法也会存在问题
终极版本
#include <memory>
#include <vector>
#include <iostream>class Widget;
std::vector<std::shared_ptr<Widget>> processedWidgets;class Widget : public std::enable_shared_from_this<Widget>
{
public:template <typename... Ts>static std::shared_ptr<Widget> create(Ts &&...params){return std::shared_ptr<Widget>(new Widget(std::forward<Ts>(params)...));}void process(){processedWidgets.emplace_back(shared_from_this());}private:Widget(int data) : _data(data){}; // privateint _data;
};int main()
{{auto w = Widget::create(1);// Widget w;w->process();}std::cout << "over" << std::endl;return 0;
}
六、std::shared_ptr不支持数组
std::shared_ptr<T []>没有这种写法