本文共 1793 字,大约阅读时间需要 5 分钟。
考虑以下情况:
class Investment{ ...}; //"投资类型",继承体系中的root class
假设这个程序库通过一个工厂函数提供我们特定的Investment对象
Investment* createInvesment(); //返回指针,指向Investment继承体系内的动态分配对象
下述函数使用该对象,由于其在动态内存中存储,因此使用者有责任在使用过后清理对象所占的动态内存:
void f(){ Investment* pInv = createInvestment(); //调用factory ... delete pInv; //释放pInv所指对象}
这个函数存在以下问题,会导致delete pInv; 这条语句执行不了:
上述情况的任何一种出现(也许一开始写代码的人不会让这样的请款发生,但是后期维护时,可能导致上述某种情况。),都将导致delete pInv;语句无法被执行,即动态内存资源没有释放,因此发生了内存泄露。 因此,在函数内delete 语句是不保险的。
为确保我们使用资源以后一定会被释放,可以借助对象进行资源管理。大体的思路是:将使用的资源包含在对象内部,而由于对象来离开其有效作用域时一定会自动调用析构函数将其销毁,因此可以在析构函数中进行资源释放。
auto_ptr 是个类似于指针的对象,也可以称为是智能指针,它指向的动态内存中分配的对象,会在使用后自动的(在析构函数中)回收内存。
原始代码的改进版:
void f(){ ... std::tr1::shared_ptrpInv(createInvestment); //调用factroy,经由shared_ptr析构函数自动删除pInv}
由于auto_ptr对象在销毁时会回收它所指向的动态内存,因此不能让多个auto_ptr指向同一个对象,因为这会导致同一片内存被回收多次,因而产生不确定行为。
为了防止上述问题, auto_ptr有一个不寻常的性质:使用copy构造函数或者 copy 赋值函数复制他们,他们会变成null,而复制所得物指向原本的auto_ptr指向的内存。要求正常复制行为的对象,不可以使用auto_ptr。比如STL的容器。
为解决上述智能指针的缺陷,可以采用:RCSP:引用计数型指针。
这个智能指针内部有一个计数器,记录着几个智能指针指向了同一个对象,只有在没有剩余的智能指针指向某一对象时,才回回收它。
无法解决环状问题:即A指向B,B指向A。 这时二者都不能被释放。
上述智能指针对象,在其析构函数中做:delete x; 而不是delete x[ ]。因此动态分配的数组不能使用上述两种指针。
标准库中没有类似的指针对象,来解决动态分配的数据的资源释放问题。实际上,使用vector 和string 就够了。
如果上述的智能指针不够我们用,那么我们也可以写出自己想要的智能指针,但是需要考虑一些细节。这些细节在条款14和条款15中描述。
转载地址:http://ifgq.baihongyu.com/