智能指针分类及简单特性

前言

智能指针的种类繁多,我听说过的就有这些:auto_ptrshared_ptrweak_ptrunique_ptrscoped_ptrscoped_arrayshared_arrayintrusive_ptr,这些智能指针看起来种类繁多,但实际上常用的就只有两三种,他们是shared_ptrweak_ptrunique_ptr,先简单了解一下这几个指针,后续再列出具体的例子和选择标准。

分类及特性

  1. auto_ptr

    这个指针历经沧桑,C++98中引入,C++11中弃用,C++17中被移除,弃用的原因主要是使用不当容易造成内存崩溃,不能够作为函数的返回值和函数的参数,也不能在容器中保存auto_ptr。

  2. shared_ptr

    据说是最好用的智能指针,使用引用计数实现,每使用它一次,内部的引用计数加1,每析构一次,内部的引用计数减1,减为0时,自动删除所指向的堆内存。shared_ptr内部的引用计数是线程安全的,但是对象的读取需要加锁。

  3. weak_ptr

    没有什么存在感,基本只在解除 shared_ptr循环引用时使用,weak_ptr没有共享资源,它的构造不会引起指针引用计数的增加,使用weak_ptr的成员函数use_count()可以观测资源的引用计数,使用成员函数lock()从被观测的shared_ptr获得一个可用的shared_ptr对象。

  4. unique_ptr

    一种比auto_ptr更加优秀的指针,可以唯一的拥有一个对象,auto_ptr通过等号赋值改变所有权后,再次引用原对象会造成内存崩溃,但是unique_ptr可以用过std::move改变所有权,并且引用原对象会在编译时期就指出错误,同时在容器算法中也可以使用,另有一种说法是说unique_ptrscoped_ptr在标准库中的一个分身。

  5. scoped_ptr

    存在于boost库而非标准库中,要把资源限制在作用域里的,并且永远不能被复制,是一种轻量级的智能指针,和const auto_ptr很像,但是可以被reset,并可以更加清楚地表明意图。

  6. scoped_array

    scoped_ptr一样,也是独享所有权的,用于管理动态数组,不支持复制,并且初始化的时候需要使用动态数组,没有重载operator*,需要使用get()函数。

  7. shared_array

    shared_ptr 一样,内部使用了引用计数,可以复制,通过参数来传递等,需要使用动态数组来初始化。

  8. intrusive_ptr

    这是一种侵入式的智能指针,内部不含有引用计数,要求被存储的对象自己实现引用计数功能,不然编译不过,还要提供intrusive_ptr_add_refintrusive_ptr_release函数接口供intrusive_ptr调用。

总结

  1. 智能指针的种类很多,但是只要掌握shared_ptrweak_ptrunique_ptr这三种指针的用法,就可以处理绝大多数问题。
  2. 智能指针的选择就根据特性来选,但是auto_ptr尽量不要用了,虽然历史悠久,但是毕竟由于各种诟病被抛弃了。
  3. 以上只给出了分类和简单特性,后续有时间会依次给出示例,指出用法和需要注意的点。
Albert Shi wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客