有以下函数:
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; //不需要显示调用析构函数 }
智能指针背后的思想是:用一个对象存储需要被自动释放的资源,并依靠对象的析构函数来释放资源。类似的思想不只是可以在指针上,还可以用在其它资源的分配和释放上。