智能指针和异常
即时程序块过早结束,智能指针类也能确保在内存不再需要时将其释放
void f(){
shared_ptr<int> sp(new int(42)); //分配一个新对象
//这段代码抛出一个异常,且在f中未被捕获
} //在函数结束时shared_ptr自动释放内存
与之对应的,当发生异常时,我们直接管理的内存是不会自动释放的。如果使用内置指针管理内存,且在new之后在对应的delete之前发生了异常,则内存是不会被是释放的。
void f(){
int *ip = new int(42); //动态分配一个新对象
//这段代码抛出异常,且在f中未捕获
delete ip; //在退出之前释放内存
}
如果在new和delete之间发生异常,且异常未在f中被捕获,则内存就永远不会被是释放了。在函数f之外没有指针指向这块内存
智能指针和哑类
假如,我们正在使用一个C/C++都使用的网络库,代码如下:
struct destination; //表示我们正在连接着什么
struct connection; //使用连接所需信息
connection connect(destination *); //打开连接
void disconnect(connection); //关闭给定连接
void f(destination &d /*其他参数*/){
//获得一个连接,记住使用完要关闭它
connection c = connect(&d);
//使用连接
//如果我们在f退出前忘记调用disconnect,就无法关闭c了
}
对于这个问题,我们使用share_ptr来保证connection被正确关闭
当一个shared_ptr被销毁时,它默认地对它管理地指针进行delete操作。为了用shared_ptr来管理一个connection,我们必须首先定义一个函数来代替delete。这个删除器函数必须能够完成对shared_ptr中保存的指针进行释放操作。在本例中,我们的删除器必须接受单个类型为connection*的参数。
void end_connection(connection *p){disconnect(*p);}
当我们创建一个shared_ptr时,可以传递一个指向删除器函数的参数
void f(destination &d /*其他参数*/){
connection c = connect(&d);
shared_ptr<connection> p(&c, end_connection);
//使用连接
//当f退出时,connection会被正确关闭
}
当p被销毁时,它不会对自己保存的指针执行delete,而是调用end_connection。end_connection会调用disconnect,从而确保连接被关闭。如果发生了异常,p同样会被销毁,从而连接被关闭