boost 库 内存管理 智能指针概述 1

智能指针库概述

计算机系统中资源有很多种,内存、文件描述符、socket、数据库连接等,程序中申请资源后必须及时归还系统。

1. RAII机制

C++程序员通常采用RAII机制(资源获取即初始化,Resource Acquisition Is Initialization),在使用资源的构造函数中申请资源,使用后再析构函数中释放资源。
栈上创建的局部对象,离开作用域后自动销毁,调用析构函数释放资源。用new从堆上创建的对象,必须明确地用对应的delete操作符销毁它。

2. 智能指针

智能指针实践了代理模式,代理了原始的“裸”指针的行为,为它添加了更多更有用的特性。
C++异常机制加入后,为了保证new对象在正确时机delete,必须编写大量的异常捕获代码释放资源,而智能指针能保证在退出作用域时,不论时正常流程或是异常退出,总调用delete析构堆上动态分配的对象,调用析构函数,释放资源。
std::auto_ptr构造函数结构new操作符或者对象工厂创建出来的对象指针作为参数,代理原始指针,重载operator*和operator->,行为类似指针,可用在大多数普通指针可用的地方。当退出作用域时,C++语言保证auto_ptr对象销毁,调用auto_prt的析构函数,进而使用delete操作符删除原始指针释放资源。
boost.smart_ptr提供六中智能指针:scoped_ptrscoped_arrayshared_ptrshared_arrayweak_ptrintrusive_ptr,都是异常安全的。
boost智能指针所指的类型T的唯一一个要求:析构函数不能抛出异常。
boost智能指针位于名字空间boost

1
2
#include <boost/smart_ptr.hpp>
using namespace std

3. auto_ptr

目前auto_ptr已不建议使用

  1. auto_ptr不能共享所有权,即不能让两个auto_ptr指向同一个对象,在用auto_ptr给其它auto_ptr赋值时,原auto_ptr失去对裸指针的引用。
  2. auto_ptr不能指向数组,因为auto_ptr在析构时只是调用delete,而数组应该调用delete[]。
  3. auto_per不能作为容器对象,STL容器中的元素经常要支持拷贝、赋值操作,在拷贝和赋值时auto_ptr会转移所有权,原对象和拷贝的对象不等价。
  4. 使用auto_ptr作为成员变量,避免资源泄露。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class A
{
public:
A()
{
cout<<"A ctor"<<endl;
}
~ A()
{
cout<<"A dtor"<<endl;
}

void print()
{
cout<<"A Print"<<endl;
}

};

void TestAutoPtr()
{
auto_ptr<A> a1(new A());
cout<<a1.get()<<endl;
auto_ptr<A> a2 = a1;
cout<<a1.get()<<endl;
cout<<a2.get()<<endl;
}