参考资料:
https://zh.cppreference.com/w/cpp/memory/shared_ptr
https://blog.csdn.net/caoshangpa/article/details/79392878
https://blog.csdn.net/yuhan61659/article/details/81563629
shared_ptr 智能指针
目的:解决用 new 动态分配的内存空间在程序的各条执行路径都能被释放的问题,避免内存泄漏
C++ 11 模板库的
将 new 运算符返回的指针 p 交给一个 shared_ptr 对象“托管”,就不必担心在哪里写delete p语句,无再写delete语句,托管 p 的 shared_ptr 对象在消亡时会自动执行delete p。其用法与指针类似。
智能指针是模板类
而不是指针。类似vector,智能指针也是模板,当创建一个智能指针时,必须提供额外的信息即指针可以指向的类型
。默认初始化的智能指针中保存着一个空指针
。智能指针的使用方式与普通指针类似。解引用一个智能指针返回它指向的对象。如果在一个条件判断中使用智能指针,效果就是检测它是否为空
。
智能指针是指向动态分配(堆)对象指针,用于生存期控制,能够确保自动正确的销毁动态分配的对象,防止内存泄露。它的一种通用实现技术是使用引用计数。每次使用它,内部的引用计数加1,每次析构一次,内部引用计数减1,减为0时,删除所指向的堆内存。
每一个shared_ptr的拷贝都指向相同的内存。在最后一个shared_ptr析构的时候, 内存才会被释放。
可以通过构造函数
、赋值函数
或者make_shared函数
初始化智能指针。
支持的方法
(来源于C++ Primer Fifth Edition 中文版):
使用shared_ptr注意事项:
(1)、不要把一个原生指针
给多个shared_ptr管理;
(2)、不要把this指针
给shared_ptr;(备注1,如果遇到要使用this指针的情况,如何解决? enable_shared_from_this
)
(3)、不要在函数实参里创建shared_ptr;
(4)、不要不加思考地把指针替换为shared_ptr来防止内存泄漏,shared_ptr并不是万能的,而且使用它们的话也是需要一定的开销的;
(5)、环状的链式结构shared_ptr将会导致内存泄漏(可以结合weak_ptr来解决);
(6)、共享拥有权的对象一般比限定作用域的对象生存更久,从而将导致更高的平均资源使用时间;
(7)、在多线程
环境中使用共享指针的代价非常大,这是因为你需要避免关于引用计数的数据竞争;
(8)、共享对象的析构器不会
在预期的时间执行;
(9)、不使用相同的内置指针值初始化(或reset)多个智能指针;
(10)、不delete get()返回的指针;
(11)、不使用get()初始化或reset另一个智能指针;
(12)、如果使用get()返回的指针,记住当最后一个对应的智能指针销毁后,你的指针就变为无效了;
(13)、如果你使用智能指针管理的资源不是new分配的内存,记住传递给它一个删除器。
enable_shared_from_this
参考资料:https://blog.csdn.net/caoshangpa/article/details/79392878
使用场合:当类A被share_ptr管理,且在类A的成员函数里需要把当前类对象作为参数传给其他函数时,就需要传递一个指向自身的share_ptr。
enable_shared_from_this是一个模板类,定义于头文件
template< class T > class enable_shared_from_this;
std::enable_shared_from_this 能让一个对象(假设其名为 t ,且已被一个 std::shared_ptr 对象 pt 管理)安全地生成其他额外的 std::shared_ptr 实例(假设名为 pt1, pt2, ... ) ,它们与 pt 共享对象 t 的所有权。
若一个类 T 继承 std::enable_shared_from_this
1.为何不直接传递this指针:
使用智能指针的初衷就是为了方便资源管理,如果在某些地方使用智能指针,某些地方使用原始指针,很容易破坏智能指针的语义,从而产生各种错误。
2.可以直接传递share_ptr
答案是不能,因为这样会造成2个非共享的share_ptr指向同一个对象,未增加引用计数导对象被析构两次。