【C++】智能指针

RAII

Resource Application Immediately Initialize,资源申请即初始化,这也是智能指针的基本原理,智能指针是RAII原理的其中一个应用。

智能指针

智能指针确保在任何情况下,动态分配的内存都能得到正确释放。

这包括程序因为异常而中断,原本用于释放内存的代码被跳过的场景。用一个动态分配的对象的地址来初始化智能指针,在析构的时候释放内存,就确保了这一点。因为析构函数总是会被执行的,这样所包含的内存也将总是会被释放。

Boost的智能指针

  1. 作用域指针

    对应的类名为boost::scoped_ptr,它的定义在boost/scoped_ptr.hpp中。一个作用域指针独占一个动态分配的对象,一个作用域指针不能传递它所包含的对象的所有权到另一个作用域指针。一旦用一个地址来初始化,这个动态分配的对象将在析构阶段释放。

    因为一个作用域指针只是简单保存和独占一个内存地址,所以boost::scoped_ptr的实现就要比std::auto_ptr简单。在不需要所有权传递的时候应该优先使用boost::scoped_ptr。在这些情况下,比起std::auto_ptr它是一个更好的选择,因为可以避免不经意间的所有权传递。

  2. 作用域数组

    作用域数组的使用方式与作用域指针相似。关键不同在于,作用域数组的析构函数使用 delete[]操作符来释放所包含的对象。因为该操作符只能用于数组对象,所以作用域数组必须通过动态分配的数组来初始化。

  3. 共享指针
    使用率最高的智能指针,如果开发环境支持的话,可以使用 memory 中定义的 std::shared_ptr。在Boost C++库里,这个智能指针命名为boost::shared_ptr,定义在boost/shared_ptr.hpp里。

    智能指针boost::shared_ptr基本上类似于boost::scoped_ptr。关键不同之处在于 boost::shared_ptr 不一定要独占一个对象。它可以和其他boost::shared_ptr类型的智能指针共享所有权。 在这种情况下,当引用对象的最后一个智能指针销毁后,对象才会被释放。因为所有权可以在boost::shared_ptr之间共享,任何一个共享指针都可以被复制,这跟 boost::scoped_ptr是不同的。这样就可以在标准容器里存储智能指针了——你不能在标准容器中存储std::auto_ptr,因为它们在拷贝的时候传递了所有权。

  4. 共享数组

    共享数组的行为类似于共享指针,方式则类似scoped_array,在此不多赘述

  5. 弱指针

    几种智能指针在不同场合可以独立使用,然而,弱指针只有在配合共享指针使用时才会有意义。
    boost::wead_ptr总是通过boost::shared_ptr来初始化的,一旦初始化之后,它基本上只提供一个有用的方法: lock()。此方法返回的boost::shared_ptr与用来初始化弱指针的共享指针共享所有权。 如果这个共享指针不含有任何对象,返回的共享指针也将是空的。

    当函数需要一个由共享指针所管理的对象,而这个对象的生存期又不依赖于这个函数时,就可以使用弱指针。 只要程序中还有一个共享指针掌管着这个对象,函数就可以使用该对象。 如果共享指针复位了,就算函数里能得到一个共享指针,对象也不存在了。

    弱指针本身对于对象的生存期没有任何影响。lock返回一个共享指针,print函数就可以安全的访问对象了。这就保证了即使另一个线程要释放对象,由于我们有返回的共享指针,对象依然存在。

  6. 介入式指针

    其实介入式指针(boost::intrusive_ptr)的工作方式和共享指针几乎一样,boost::shared_ptr 在内部记录着引用到某个对象的共享指针的数量,而对介入式指针,程序员就得自己来做记录。对于框架对象来说这就特别有用,因为它们记录着自身被引用的次数。

  7. 指针容器

    在用C语言时,如果我们要创建一个动态数组,我们可以new一个,但是这样使用十分麻烦,因此可以选择更高级写的容器vector,它可以很好的动态管理数组(push_back、erase等)。对应的,boost中也有这样的指针:

    boost::ptr_vector专门用于动态分配的对象,它使用起来更容易也更高效。 boost::ptr_vector 独占它所包含的对象,因而容器之外的共享指针不能共享所有权,这跟 std::vector<boost::shared_ptr<int>> 相反。

    除了boost::ptr_vector之外,专门用于管理动态分配对象的容器还包括:boost::ptr_deque, boost::ptr_list,boost::ptr_set,boost::ptr_map,boost::ptr_unordered_set和 boost::ptr_unordered_map。这些容器等价于C++标准里提供的那些。最后两个容器对应于std::unordered_set和std::unordered_map,它们作为技术报告1的一部分加入C++标准。如果所使用的C++标准实现不支持技术报告1的话,还可以使用Boost C++库里实现的 boost::unordered_set和boost::unordered_map。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值