auto_ptr类
auto_ptr是一个模板类,用于管理动态内存分配。
请看下面的函数:
void remodel (string& str) { string * ps = new string(str); ... str = *ps; return; }
上述代码存在这样一个缺陷:没有收回函数中分配的内存。
解决方法:在return前加上delete,如下所示:
void remodel (string& str) { string * ps = new string(str); ... str = *ps; delete ps; return; }
上述解决方法并不是最佳的,因为编程者有时可能忘了,有时可能在不经意间删除或注释掉了这些代码。而且即使没有这些问题,也可能有其他问题。如:
void remodel (string& str) { string * ps = new string(str); ... if (weird_thing()) throw exception(); str = *ps; delete ps; return; }
在上述代码中,当出现异常时,delete将不被执行,因此将导致内存泄露。
解决方法:如果一个指针对象,那么可以在对象过期时,让它的析构函数删除被指向的内存。这就是auto_ptr背后的思想。
auto_ptr的头文件为<memory>
使用方法:
auto_ptr<double>pd(new double); auto_ptr<string>ps(new string);
上述函数经修改后如下所示:
void remodel (string& str) { auto_ptr<string>ps (new string(str)); ... if (weird_thing()) throw exception(); str = *ps; return; }
注意:auto_ptr的构造函数是显式的,这意味着不存在从指针到auto_ptr对象的隐式类型转换:
auto_ptr<double>pd; double *p_reg = new double; pd = p_reg; //not allowed p_reg = pd; //not allowed pd = auto_ptr<double>(p_reg);//allowed auto_ptr<double>pauto(p_reg);//allowed
注意事项:
- 只能对new分配的内存使用auto_ptr对象,而不要对由new[]分配的或通过声明变量分配的内存使用它。
- 由于auto_ptr被销毁时会自动删除它所指之物,所以不能让多个auto_ptr同时指向同一对象,以避免对象被删除一次以上。为了预防这个问题,auto_ptr有一个不寻常的性质:若通过copy构造函数或copy assignment操作符赋值它们,它们会变成null,而复制得到的指针将取得资源的唯一所有权。
PS:
由于auto_ptr的复制行为的特殊性,因此引入了“引用计数型智慧指针”(reference-counting smart pointer;RCSP)。RCSP也是个智能指针,可以持续追踪共有多少对象指向某个资源,并在无人指向它时自动删除该资源。但是它无法打破环状引用(例如两个其实已经没被使用的对象彼此互值,因而好像还在“被使用”状态)。
TR1的tr1::shared_ptr就是个RCSP