四类智能指针 C++ 我看这内存还咋泄露!


啥叫智能指针呢?

所谓 智能 就是说 在 平常申请内存时 一定时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);// 解除对内存的占用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值