C++智能指针——揭秘auto_ptr为什么被摒弃?

一般情况下,使用栈上的内存资源都是系统来开辟内存,使用完之后再由系统释放掉该内存。相反,使用堆上的内存资源时,需要手动使用new关键字来开辟内存,使用完之后再用delete关键字来手动释放内存资源,如果忘了释放内存资源,将会造成内存泄漏,存在不安全隐患。那么如何实现手动开辟系统内存,然后让系统来完成内存释放呢?
C++智能指针——揭秘auto_ptr为什么被摒弃?_第1张图片
这里我们引入智能指针的思想:在使用系统内存时,手动开辟堆内存,生成相应的对象,使对象的指针指向堆内存,对象在栈上开辟当对象的生存周期结束后,如果将堆内存的释放加入析构函数中,通过调用析构函数由系统来释放对象使用的资源,从而实现手动开辟内存,系统释放内存

在C++中,存在四种类型的智能指针,分别是auto_ptr,unique-ptr,shared_ptr,weak_ptr。其中auto_ptr已经被摒弃,unique_ptr和shared_ptr的使用必须支持C++11特性。同时使用智能指针是需要引入头文件头文件。

究竟是什么原因导致auto_ptr被摒弃呢?

先来看一下下面代码:

auto_ptr ps1 (new string ("hello world!\n"))
auto_ptr ps2
ps2 = ps1

如果两个auto_ptr指针指向同一个对象时,当该对象的生存周期结束后,系统会调用析构函数,这样导致的结果是程序对同一个对象删除了2次,造成程序出错。

那么该如何解决这个问题呢?这个问题看似很难解决,其实解决的方法却有很多:
1、通过定义赋值运算符,实现深拷贝,从而两个指针指向不同的两个对象,其中一个对象是另一个对象的副本;
2、将对象的删除所有权设置成唯一。即只允许一个对象拥有删除对象的权力,其他指针只能指向该对象,不享有删除对象的权力。auto_ptr、unique_ptr都是用这样的机制,但是后者比前者更加的严格;
3、采用引用计数的方法。当有一个一个指针指向对象时,引用计数加1,当指向该对象的指针销毁时,引用计数减1,当且仅当最后一个指向该对象的指针销毁时,也就是引用计数为0时,对象才能够被删除。智能指针shared-ptr就是采用该机制来实现的。

auto_ptr导致的问题在于,当所有权转让之后,原来的指针被用来访问原来指向的对象,当程序访问该指针指向的内容时,会发现这是一个悬空指针,程序就会出错,但是如果换成shared_ptr程序就能正常运行。

你可能感兴趣的:(C/C++)