啥叫智能指针呢?
所谓 智能 就是说 在 平常申请内存时 一定时new delete 成对出现,但是偶尔忘写了,就GG了,不能解放人的生产力。因此 搞了 这个玩意儿 防止你 new 一块新内存的时候 忘记 写 delete 啦,用了这玩意,从此,妈妈再也不用担心我delete忘写了。就是这么拽。
所谓 指针 呢, 并不是说 这玩意 就是个 普通的指针,那是不可能滴,高级玩意的出现 这不要整点花活。它的这个名字 就是说 具有 指针的 特性 ,可以把它当成指针 来用。跟 指鹿为马 字面意思 也差不多。
哪四类?
auto_ptr
C++98 版本 里面的 智能指针。 但是因为存在着内存崩溃问题,被弃用了。具体代码 如下:
#include<memory>
#include<iostream>
using namespace std;
void main(){
auto_ptr<int> ptr1(new int(10));
auto_ptr<int> ptr2;
ptr2 = ptr1; //ptr2 会 剥夺 ptr1 的所有权
cout<<*ptr1<<endl; // 可能会报错, 内存出现了崩溃,ptr1 指向的变量值 不知道去哪了
}
结果如下:
如果代码改成这样:
#include<memory>
#include<iostream>
using namespace std;
void main(){
auto_ptr<int> ptr1(new int(10));
auto_ptr<int> ptr2;
ptr2 = ptr1; //ptr2 会 剥夺 ptr1 的所有权
cout<<*ptr2<<endl; // 可能会报错, 内存出现了崩溃,ptr1 指向的变量值 不知道去哪了
}
结果正常。因此呢,由于这个缺点,所以在C++11 当中 把 这个 auto_ptr 给 废弃了, 进而 使用 unique_ptr 给取代了。欲知unique_ptr 是啥 ,请见 下节博客,嘿哈。
unique_ptr
unique_ptr 保证对象 在同一时间 只会被 一个 智能指针 指向。 针对避免 资源内存 泄露 非常有帮助。
具体代码如下:
#include<memory>
#include<iostream>
using namespace std;
int main(){
unique_ptr<int> ptr1(new int(10));
unique_ptr<int> ptr2;
ptr2 = ptr1; // ptr1 独占 那块内存 , 编译不通过
cout<<*ptr2<<endl; // 。
return 0;
}
编译报错,归根结底 是unique_ptr 对资源的独占。
了解了 这种 独占资源 的 智能指针, 那么 有没有 一个 智能指针 能够 实现 资源的共享。当然有的。
他就是 shared_ptr。下面我们讲解一下 这个 指针。
shared_ptr
多个智能指针 可以 同时 指向 同一个 对象 , 只不过这个指针里面 有一个 特别的 地方, 他会有一个 函数 use_count() 来记录了 这个 对象 被 多少个指针 所用了。如果取消 某个 指针 指向 该对象,有一个reset() 函数 ,会让 该指针 变成 空指针。 那么 use_count 的计数 也会 减少1,当 计数 为0时,该对象 被 释放。
示例代码 如下:
#include<memory>
#include<iostream>
using namespace std;
int main(){
shared_ptr<int> ptr1(new int(10));
shared_ptr<int> ptr2;
ptr2 = ptr1;
cout<<ptr1.use_count()<<endl; //打印 该资源的引用计数
cout<<ptr2.use_count()<<endl; //
ptr2.reset();
cout<<ptr1.use_count()<<endl; //打印 该资源的引用计数
cout<<ptr2.use_count()<<endl; //
cout<<ptr1<<endl; //打印 ptr1
cout<<ptr2<<endl
return 0; //打印 ptr2
}
输出结果:
这个指针呢,存在这一个特殊的情况 无法 处理 , 当 两个 shared_ptr 相互引用时,也称为循环引用时 ,所以 use_count 计数 会 永远不为0。这种情况下呢,就会造成 资源无法被 释放掉 ,造成 内存的 泄露。为了解决 这个问题呢,所以 我们 引用了 下面的 这个 智能 指针,weak_ptr。
weak_ptr
weak_ptr 一定是 配合 着shared_ptr 使用的。它的构造函数的对象时 shard_ptr 指针 以及weak_ptr 指针。 它对 资源的 占有 以及 不占有 均不会 造成 shared_ptr 的对象 的 引用次数 增加或者减少。
这里面就不举例了。什么时候会用呢? 就是 当 两个 shared_ptr 相互 引用 计数 增加 时 , 需要 把 其中 一个 shared_ptr 变成 weak_ptr
本质是撒?
智能指针 本质上 呢 是一个 类。
因此呢,当通过 这个类 产生 的 对象 也就是 我们 通过 智能指针生成的 指针 。超出 类的 作用域 后 析构函数 就会 自动 调用 。
常用的函数接口:
T* get(); //得到原始指针
T* operator->(); // 重载 -> 运算符
T& operator*(); // 重载 -> *
T& operator=(); // 重载 =
void reset(T* ptr = nullptr);// 解除对内存的占用