1.问题
简单一句话总结,就是把申请的资源放在对象中,利用对象的析构函数,自动将资源释放,防止自己忘记delete。
1.假设使用一个来塑膜投资行为的程序库,所有的投资类型,继承一个root class Investment{...}
Investment{...};..
2.这个程序库系统通过工厂函数,创建特定的Investment对象。
Investment* createInvestment()
3.例
void func()
{
Investment * ptr = createInvestment();//调用工厂函数
....
delete ptr;//删除ptr所指对象
}
这个func看起来没什么问题
1、但是如果func过早的return,控制流就绝对不会触及到 delete。
2.如果delete在循环之中,过早的goto也会导致,资源泄漏。
3.如果...区域抛出异常,控制流也不会临行delete。
2.解决方法
有很多的heap区的内存,但是确被作用单一作用域,或者函数,他们应该在控制流离开那个区块时被释放。
标准程序库提供的auto_ptr,正是针对这种情况的产品,智能指针是一个类指针对象
(pointer - like),智能指针的析构函数会对指向的对象进行delete。
例:
void func()
{
std::auto_ptr< Investment> ptr (createInvestment());
}
以上面的例子引出,资源管理的两个关键想法。
1.获得资源之后,立刻放入对象管理
2.管理对象用析构函数确保对象的资源被释放。
注意
1.auto_ptr出作用域,会把指向的内容销毁,如果当多个auto_ptr指向同一个资源,那么会出现多次释放的问题。这种行为是被禁止的,如果auto_ptr出现赋值和拷贝,只有被赋值的auto_ptr会指向资源,本身会变为nullptr
std::auto_ptr< Investment> ptr1 (createInvestment());
std::auto_ptr< Investment> ptr2(ptr1)//ptr1为空,ptr2指向资源
std::auto_ptr< Investment> ptr3 = ptr2 //ptr2为空,ptr3指向资源
2.如果想正常的进行拷贝,使用shared_ptr,shared_ptr的析构采用引用计数的方式,如果有一个指针指向资源,那么计数就会++,如果有一个指向该资源的shared_ptr析构了,计数就会--,计数减到0,才会将资源释放。
注意
auto_ptr和shared_ptr释放资源都是delete而非delete[],所以用他们指向一个动态分配的数组是一个愚蠢的主意,因为vector和string是完全可以替代数组的。
std::auto_ptr<string> aps (new string[10]);//愚蠢
std::shared_ptr<int> arr (new int[10]);//愚蠢