玖叶教程网

前端编程开发入门

「C++基础篇」智能指针 auto_ptr/unique_ptr/shared_ptr

指针与动态内存管理(堆)

从上述代码中,可以很明显的发现其中的问题。每当调用函数时都会从堆中分配内存,但却在操作结束后没有进行内存回收。这将导致内存泄漏。一般而言,不能很好的对内存进行管理的C++程序员不是一个合格的程序员。

一种解决方法就是,时时刻刻都记得释放自己申请的内存。这不是一件简单的事,特别是在大型项目开发过程中。

时刻记得释放内存并不能总能有效。当发生异常的时候,delete ps将不会被执行,进而导致内存泄漏。

那如何能保证任何时候都能做到对申请的堆内存进行释放了?

我们知道的是当函数dosomething()结束时(无论是正常返回还是异常终止),局部变量都会结束生存周期,也就是指针变量ps将会被释放。如果ps释放时,其指向的内存也能被释放这不就满足我们的目的--总是做到对申请的内存进行释放了吗?深刻理解面向对象编程理念的话,这种情况可以使用析构函数做到,也就是对象消亡时调用对象的析构函数对其指向的动态内存进行释放--这就是智能指针的核心思想!

为什么需要智能指针

① 通过智能指针的析构函数,自动管理内存释放。

② 智能指针可以确保总能正常释放内存,即使是异常发生。

如何设计智能指针

为了不出现多指针指向统一内存区(其实不必过度考虑这一点,如后面将讲到的shared_ptr是允许多个指针指向同一内存的),初始的智能指针模板类进行了如下设计:

a) 定义赋值运算符,执行深拷贝。使指针指向不同对象。

b) 建立所有权,对于特定的对象只能有一个智能指针拥有它,使用移动赋值函数转让权限,使只有拥有对象的智能指针可以删除对象。如,auto_ptr。

但这种auto_ptr运行直接转让权限的操作将会导致留下悬浮指针ap,它将不会再指向有效数据,如果程序后面试图使用ap这将导致出现不确定行为或者崩溃。因此unique_ptr被设计出。

unique_ptr比auto_ptr更安全

unique_ptr不允许对一个左值进行权限转移,因为这会留下一个有隐患的悬浮指针(不理解悬浮指针的危害的请查看本人的之前【「C++基础篇」深拷贝与浅拷贝】文章)。但允许对右值临时对象进行权限转移操作,因为右值临时对象将在转移完权限后就销毁。

unique_ptr允许申请数组内存unique_ptr<double []> up(new double[5]),auto_ptr不能。

shared_ptr最为贴近原始的指针

就像前面说的,多个指针指向同一个内存并非不可以,只要正确的释放内存即可。而shared_ptr使用引用计数做到了这一点使得智能指针更加贴近原始的指针

赋值时计数加1,指针过期时计数减1。当最后一个指针过期时,才调用delete。这是shared_ptr。

shared_ptr可以接收一个临时的unique_ptr右值但不能指向unique_ptr左值。

除了上面的几个智能指针外,还有weak_ptr,这将会在以后的多线程篇中仔细讲解。

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言