为什么要使用智能指针?
在剖析源码的过程以及我们使用C++进行编程的过程中,我们经常会看到智能指针的身影。那么为什么要使用智能指针呢?
其实,使用智能指针最重要的原因就是防止内存泄漏,它可以帮助我们管理动态分配的内存的,然后自动释放new出来的内存空间。
内存泄漏
就是分配的内存没有释放,一般指的是堆内存(没有名字,只能用指针来指向)没有释放,也再没有机会释放了,也可能写了delete,但是程序没有运行到return的地方,程序return掉了或者运行剖出异常了,这就会造成内存泄漏。所以采用使用智能指针来管理new出来的堆上的内存,一般栈上的对象出作用域自动释放 ,不需要我们手动释放
不带引用计数
auto_ptr 不推荐
auto_ptr 是c++ 98定义的智能指针模板,其定义了管理指针的对象,可以将new 获得(直接或间接)的地址赋给这种对象。当对象过期时,其析构函数将使用delete 来释放内存,但是在赋值操作的时候,auto_ptr本质上是让最后一个指针管理资源,前面所有的都置位nulptr,都不能使用了,用户也不知道。不推荐,尤其是在容器内使用,会导致之前的容器全部不存在。
scoped_ptr 不推荐
scoped_ptr:C++11,已经把这个函数的拷贝构造和赋值给删除了,用户在使用的时候,会直接报错。所以使用比较少。
unique_ptr 推荐
unique_ptr:C++11 虽然把这个函数的拷贝构造和赋值给删除了,但是提供了右值引用的拷贝构造函数和赋值构造,临时对象或者进行std::move()强转都可以进行正常的拷贝构造和赋值,在使用std::move()时,用户很明确的知道指向原来对象的资源进行了转移,不能使用了。
带引用计数
带引用计数,给每一个对象资源,匹配一个引用计数,当一个智能指针使用这个资源的时候,计数+1,出作用域不使用资源的时候,计数-1,当计数为0的时候,自动释放资源,这样多个智能指针可以管理同一个资源。
shared_ptr
shared_ptr(强智能指针),可以改变资源的引用计数;但是,强智能指针会出现交叉引用的问题。 两个对象互相引用,这样调用的时候,两个强智能指针引用计数都为2,在析构的时候,引用计数减一,但是还不到0,所以达不到析构的条件,这样就永远析构不了,所以有了弱智能指针。
weak_ptr
weak_ptr(弱智能指针),不会改变资源的引用计数,只是观察是否存活,不能使用它来调用资源,除非调用lock方法提升为强智能指针;
一般使用弱智能指针观察强智能指针,然后强智能指针在观察资源。