catalog
智能指针的头文件
当我们去看 unique_ptr
或 shared_ptr
的头文件时, 虽然他是在: <bits/unique_ptr.h>
这个文件
但是, 会有提示:
/** @file bits/shared_ptr.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
当我们要使用他时, 应该: #include <memory>
shared_ptr的release操作
shared_ptr
是没有 release
操作的!!! 这意味着: shared_ptr 必须和 new
操作 关联在一起, 否则就出错了!!
换句话说, 即: shared_ptr 不可以绑定: 非动态内存的对象!!
T data; ' 全局对象 或 局部对象, 反正不是new出来的 '
shared_ptr< T> ptr( &data);
好了, 这个代码就彻底死了
当ues_count == 1
的那个ptr, 析构函数里, 一定会调用: data.~T()
而data
离开作用域, 也会调用 data.~T()
两次析构, 出错了
什么方式都救不了; 你使用ptr.reset()
, 如果ptr.use_count() = 1
, 还是会调用 析构!!!
解释下, 为什么shared_ptr 没有像unique_ptr一样, 有个release函数
之所以用shared_ptr, 即: 你有很多指针, 会指向同一个内存; 而这么多指针, 你很难管理;
如果这些指针, 你很好管理, 你都知道哪个是哪个, 那何必使用 (智能)指针呢? 所谓智能, 即你不知道该怎么管理
即此时很多指针, 你不知道该怎么管理 (所谓管理, 即不知道该什么时候 delete掉哪个指针)
假如支持release操作, T * p = ptr.release()
, 这样做, 你可能有2个目的:
-
(1, 得到p 然后调用
delete p
) 如果不调用delete, 你使用get()也可以
又有两种情况: (1, 此时ptr.use_count=1) (2, ptr.use_count > 1)
如果是1: 你使用ptr.reset()
或 让ptr析构, 也可以达到相同目的
如果是2: 你此时delete p;后, shared_ptr还是会析构, 造成两次析构
故, 这个原因不成立 -
(2, 单纯的 想要解除
ptr
与内存的关系)
又有两种情况: (1, 此时ptr.use_count=1) (2, ptr.use_count > 1)
如果是1: 造成内存泄漏!!
如果是2: 你使用ptr.reset()
也可以呀~
故, 综上, 为shared_ptr 添加 release()函数, 并无作用
智能指针
裸指针
T * ptr = new T
我们日常在申请动态内存时, 通常是使用这种方式.
但是这种方式, 比较考验程序员的水平.
比如: T * p1, p2, p3;
这3个指针, 指向同一个内存.
当你要把这块内存 给delete掉: delete p1; p1 = nullptr;
但是, 此时p2 和 p3, 这两个指针; 他们并没用置空 但是, 他俩指向的内存 已经delete掉了.
除非, 你手动的 给p2 和 p3, 也给 delete掉
, 但这通常是很累人的.
所以, 引入 智能指针
::std::auto_ptr
, 他目前已经完全被unique_ptr
所取代.::std::unique_ptr
::std::shared_ptr
::std::weak_ptr
shared_ptr
顾名思义: 共享式的 指针. 允许多个指针, 同时指向 同一块内存.
构造函数
shared_ptr< Obj> ptr;
这个指针, 是指向nullptr
的 , 即: 类似于Obj * ptr = nullptr
shared_ptr< Obj> ptr( new Obj);
(注意, shared_ptr类构造是 explicit的, 所以:ptr = new Obj;
是不可行的
(不推荐:Obj * p = new Obj; shared_ptr< Obj> ptr( p);
使用智能指针, 就应该 摒弃掉 以前的裸指针)
*取内容
shared_ptr< Obj> ptr( new Obj);
( *ptr).func(); ' *ptr取内容, 即一个Obj对象. 注意要带括号, 优先级 '
get函数 取指针
shared_ptr< Obj> ptr( new Obj);
( ptr.get())->func(); ' get函数, 获取该指针所指向的内存地址 (如果问空, 则返回nullptr) '
use_count函数
shared_ptr类, 有个use_count()函数, 表示: 该ptr所指向的内存, 被多少个shared_ptr指针所指向
{
shared_ptr< Obj> ptr( new Obj);
' ptr.use_count() == 1 '
{
auto a = ptr;
' a/ptr .use_count() == 2 '
}
' ptr.use_count() == 1 '
}
' 出了这个作用域, ptr析构时, 他所指向的内存的 use_count变为0; '
' 会触发: Obj的析构!! '
shared_ptr< T> ptr