有以下函数:
void function()
{
Awesome * obj = new Awesome;
obj->process();
delete obj;
}
当process
发生异常时,function
没有捕获异常;异常将会被传递到function
的调用者,而process
之后的代码则被跳过了,导致内存泄漏。
void function()
{
Awesome * obj = new Awesome;
try
{
obj->process();
}
catch(...)
{
delete obj;
throw;
}
delete obj;
}
通过catch
捕获异常并确保资源释放,但缺点是必须在正常运行情况下和异常情况下写多份资源清除代码。这样的代码写起来心烦又难以维护,而且看上去好像存在问题。
我们把__引入局部对象来管理这些动态资源,并把清除代码放入函数内局部对象的析构函数里,因为局部对象内存由栈管理,在离开生命周期后自动释放,在避免重复代码同时确保了没有资源泄漏__。
具体方法为用一个类指针对象代替指针。这个对象具有类似指针的行为,同时在其析构时释放资源,称为smart pointers
(智能指针)。C++11
提供了三种智能指针:shared_ptr
、unique_ptr
、weak_ptr
。在C++11
之前只有auto_ptr
。
template <typename _Tp>
class auto_ptr
{
private:
_Tp *_M_ptr;
public:
explicit auto_ptr(_Tp *__p = 0) throw();
auto_ptr(auto_ptr &__a) throw();
auto_ptr &operator=(auto_ptr &__a) throw();
~auto_ptr();
_Tp &operator*() const throw();
_Tp *operator->() const throw();
_Tp *get() const throw();
_Tp *release() throw();
void reset(_Tp *__p = 0) throw();
};
- 指针资源自动释放
- 支持拷贝构造
- 支持
operator-> / operator *
解引用 - 保持指针持有者唯一
auto_ptr
具备原始指针的所有功能,两者的使用场景完全等同。修改后的函数如下:
void function()
{
auto_ptr<Awesome> obj();
obj->process();
//delete obj; //不需要显示调用析构函数
}
智能指针背后的思想是:用一个对象存储需要被自动释放的资源,并依靠对象的析构函数来释放资源。类似的思想不只是可以在指针上,还可以用在其它资源的分配和释放上。