智能指针

智能指针就是一个类,当超出了类的作用域时,类会自动调用析构函数
auto_ptr, shared_ptr, weak_ptr, unique_ptr
其中后三个是c++11支持,并且第一个已经被c++11弃用。
作用:
智能指针的作用是管理一个指针,因为存在以下这种情况:
申请的空间在函数结束时忘记释放,
造成内存泄漏。使用智能指针可以很大程度上的避免这个问题,
因为智能指针就是一个类,当超出了类的作用域时,
类会自动调用析构函数,析构函数会自动释放资源。
所以智能指针的作用原理就是在函数结束时自动释放内存空间,
不需要手动释放内存空间。
1、auto_ptr(c++98的方案,cpp11已经抛弃)采用所有权模式。
##所有权独享。
缺点是:存在潜在的内存崩溃问题!
auto_ptr< string> p1 (new string ("I reigned lonely as a cloud.”));
auto_ptr p2;p2 = p1;
//auto_ptr不会报错.此时不会报错,p2剥夺了p1的所有权,
但是当程序运行时访问p1将会报错。
所以auto_ptr的缺点是:存在潜在的内存崩溃问题!
两次删除同一个对象,不允许。
2、unique_ptr(替换auto_ptr)unique_ptr实现独占式拥有或
严格拥有概念,对于简单的赋值或者拷贝都是不允许的。
保证同一时间内只有一个智能指针可以指向该对象。
它对于避免资源泄露(例如“以new创建对象后因为发生异常而忘记调用delete”)特别有用。采用所有权模式。

unique_ptr p3 (new string (“auto”));
unique_ptr p4;
p4 = p3;//此时会报错!! 不支持拷贝和赋值
//编译器认为p4=p3非法,避免了p3不再指向有效数据的问题。
因此,unique_ptr比auto_ptr更安全。
3、shared_ptr
shared_ptr实现共享式拥有概念。多个智能指针可以指向相同对象,
该对象和其相关资源会在“最后一个引用被销毁”时候释放。
从名字share就可以看出了资源可以被多个指针共享,
它使用计数机制来表明资源被几个指针共享。
可以通过成员函数use_count()来查看资源的所有者个数。
除了可以通过new来构造,
还可以通过传入auto_ptr, unique_ptr,weak_ptr来构造。
当我们调用release()时,当前指针会释放资源所有权,计数减一。
当计数等于0时,资源会被释放。
shared_ptr 是为了解决 auto_ptr 在对象所有权上的局限性(auto_ptr 是独占的),
在使用引用计数的机制上提供了可以共享所有权的智能指针。
4、weak_ptr
weak_ptr 是一种不控制对象生命周期的智能指针, 它指向一个
shared_ptr 管理的对象.
进行该对象的内存管理的是那个强引用的 shared_ptr. weak_ptr只是提供了对管理对象的一个访问手段。
weak_ptr 设计的目的是为配合 shared_ptr 而引入的一种智能指针来协助 shared_ptr 工作,
它只可以从一个 shared_ptr 或另一个 weak_ptr 对象构造, 它的构造和析构不会引起引用记数的增加或减少。

weak_ptr是用来解决shared_ptr相互引用时的死锁问题,如果说两个shared_ptr相互引用,
那么这两个指针的引用计数永远不可能下降为0,资源永远不会释放。它是对对象的一种弱引用,不会增加对象的引用计数,
和shared_ptr之间可以相互转化,shared_ptr可以直接赋值给它,它可以通过调用lock函数来获得shared_ptr。

面试问题
介绍智能指针
智能指针主要用于管理在堆上分配的内存,它将普通的指针封装为一个栈对象。当栈对象的生存周期结束后,
会在析构函数中释放掉申请的内存,从而防止内存泄漏。
C++ 11中最常用的智能指针类型为shared_ptr,
它采用引用计数的方法,记录当前内存资源被多少个智能指针引用。该引用计数的内存在堆上分配。
当新增一个时引用计数加1,当过期时引用计数减一。只有引用计数为0时,智能指针才会自动释放引用的内存资源。
对shared_ptr进行初始化时不能将一个普通指针直接赋值给智能指针,因为一个是指针,一个是类。
可以通过make_shared函数或者通过构造函数传入普通指针。
并可以通过get函数获得普通指针。

智能指针内存泄漏情况
当两个对象相互使用一个shared_ptr成员变量指向对方,
会造成循环引用,使引用计数失效,从而导致内存泄漏。例如:

上述代码中,parent有一个shared_ptr类型的成员指向孩子,
而child也有一个shared_ptr类型的成员指向父亲。
然后在创建孩子和父亲对象时也使用了智能指针c和p,
随后将c和p分别又赋值给child的智能指针成员parent和parent的智能指针成员child。
从而形成了一个循环引用:

智能指针内存泄漏解决
为了解决循环引用导致的内存泄漏,引入了weak_ptr弱指针,
weak_ptr的构造函数不会修改引用计数的值,
从而不会对对象的内存进行管理,其类似一个普通指针,但不指向引用计数的共享内存,
但是其可以检测到所管理的对象是否已经被释放,从而避免非法访问。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值