C++智能指针

什么是智能指针?智能指针的原理

将基本类型指针封装为类对象指针(这个类肯定是个模板,以适应不同基本类型的需求),并 在析构函数里编写delete语句删除指针指向的内存空间。
智能指针是一个类,这个类的构造函数中传入一个普通指针,析构函数中释放传入的指针。智 能指针的类都是栈上的对象,所以当函数(或程序)结束时会自动被释放,
智能指针就是一种栈上创建的对象,函数退出时会调用其析构函数,这个析构函数里面往往就 是一堆计数之类的条件判断,如果达到某个条件,就把真正指针指向的空间给释放了。

注意事项:不能将指针直接赋值给一个智能指针,一个是,一个是指针

常用的智能指针

智能指针在C++11版本之后提供,包含在头文件<memory>中,auto_ptr、shared_ptr、 unique_ptr、weak_ptr

1)std::auto_ptr,

有很多问题。 不支持复制(拷贝构造函数)和赋值(operator =),但 复制或赋值的时候不会提示出错。所以可能会造成程序崩溃,比如

auto_ptr<string> p1(new string ("auto") ; //#1 
auto_ptr<string> p2;                                    //#2 
p2 = p1;                                                        //#3

在语句#3中,p2接管string对象的所有权后,p1的所有权将被剥夺。前面说过,这是好事, 可防止p1和p2的析构函数试图刪同—个对象; 但如果程序随后试图使用p1,这将是件坏事,因为p1不再指向有效的数据。如果再访问p1指 向的内容则会导致程序崩溃。
auto_ptr是C++98提供的解决方案,C+11已将将其摒弃,摒弃auto_ptr的原因,一句话总结 就是:避免潜在的内存崩溃问题。

2)unique_ptr

它也不支持复制和赋值,但比auto_ptr好,直接赋值会编译出 错。实在想赋值的话,需要使用:std::move。例如:

std::unique_ptr<int> p1(new int(5))          // #4 
std::unique_ptr<int> p2 = p1; // 编译会出错         //#5 
std::unique_ptr<int> p3 = std::move(p1); // 转移所有权, 现在那块内存归p3 所有, p1成为无效的指针. //#6

编译器认为语句#5非法,因此,unique_ptr比auto_ptr更安全。

但unique_ptr还有更聪明的地方。 有时候,会将一个智能指针赋给另一个并不会留下危险的 悬挂指针。当程序试图将一个 unique_ptr 赋值给另一个时,如果源 unique_ptr 是个临时右 值,编译器允许这么做;如果源 unique_ptr 将存在一段时间,编译器将禁止这么做

unique_ptr<string> pu1(new string ("hello world")); 
unique_ptr<string> pu2; 
pu2 = pu1;                                      // #1 not allowed 
unique_ptr<string> pu3; 
pu3 = unique_ptr<string>(new string ("You"));   // #2 allowed

其中#1留下悬挂的unique_ptr(pu1),这可能导致危害。而#2不会留下悬挂的unique_ptr, 因为它调用 unique_ptr 的构造函数,该构造函数创建的临时对象在其所有权让给 pu3 后就 会被销毁。这种随情况而已的行为表明,unique_ptr 优于允许两种赋值的auto_ptr 。

3) shared_ptr

基于引用计数的智能指针。可随意赋值,直到内存的引用 计数为0的时候这个内存会被释放。

4) weak_ptr

弱引用。 引用计数有一个问题就是互相引用形成环,这样 两个指针指向的内存都无法释放。需要手动打破循环引用或使用weak_ptr。顾名思义, weak_ptr是一个弱引用,只引用,不计数。如果一块内存被shared_ptr和weak_ptr同时引 用,当所有shared_ptr析构了之后,不管还有没有weak_ptr引用该内存,内存也会被释放。 所以weak_ptr不保证它指向的内存一定是有效的,在使用之前需要检查weak_ptr是否为空指 针。

智能指针的作用

C++程序设计中使用堆内存是非常频繁的操作,堆内存的申请和释放都由程序员自己管理。程 序员自己管理堆内存可以提高了程序的效率,但是整体来说堆内存的管理是麻烦的,C++11 中引入了智能指针的概念,方便管理堆内存。使用普通指针,容易造成堆内存泄露(忘记释 放),二次释放,野指针,程序发生异常时内存泄露等问题等,使用智能指针能更好的管理堆 内存。
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值