auto_ptr的使用

#include <iostream>
#include <memory>
using namespace std;
class TC
{
public:
TC(){cout<<"TC()"<<endl;}
~TC(){cout<<"~TC()"<<endl;}
};
void foo(bool isThrow)
{
auto_ptr<TC> pTC(new TC); //方法2
//TC *pTC = new TC; //方法1
try
{
if(isThrow)
throw "haha";
}
catch(const char* e)
{
//delete pTC; //方法1
throw;
}
//delete pTC; //方法1
}
int main()
{
try
{
foo(true);
}
catch(...)
{
cout<<"caught"<<endl;
}
system("pause");
}

1.如果采用方案1,那么必须考虑到函数在因throw异常的时候释放所分配的内存。 这样造成的结果是在每个分支处都要很小心的手动 delete pTC;

2.如果采用方案2,那就无需操心何时释放内存,不管foo()因何原因退出, 栈上对象pTC的析构函数都将调用,因此托管在之中的指针所指的内存必然安全释放。 至此,智能指针的优点已经很明了了。 但是要注意使用中的一个陷阱,那就是指针的托管权是会转移的。 例如在上例中,如果 auto_ptr<TC> pTC(new TC); auto_ptr<TC> pTC1=pTC; 那么,pTC1将拥有该指针,而pTC没有了,如果再用pTC去引用,必然导致内存错误。
要避免这个问题,可以考虑使用采用了引用计数的智能指针,例如boost::shared_ptr等,auto_ptr不会降低程序的效率,但auto_ptr不适用于数组,auto_ptr根本不可以大规模使用。 shared_ptr也要配合weaked_ptr,否则会很容易触发循环引用而永远无法回收内存。理论上,合理使用容器加智能指针,C++可以完全避免内存泄露,效率只有微不足道的下降。

这里我们有几点要注意:
1) 因为auto_ptr析构的时候肯定会删除他所拥有的那个对象,所有我们就要注意了,一个萝卜一个坑,两个auto_ptr不能同时拥有同一个对象。像这样:
int*p=newint(0);
auto_ptr<int>ap1(p);
auto_ptr<int>ap2(p);
因为ap1与ap2都认为指针p是归它管的,在析构时都试图删除p, 两次删除同一个对象的行为在C++标准中是未定义的。所以我们必须防止这样使用auto_ptr.
2) 考虑下面这种用法:
int*pa=newint[10];
auto_ptr<int>ap(pa);
因为auto_ptr的析构函数中删除指针用的是delete,而不是delete [],所以我们不应该用auto_ptr来管理一个数组指针。
3) 构造函数的explicit关键词有效阻止从一个“裸”指针隐式转换成auto_ptr类型。

你可能感兴趣的:(auto_ptr的使用)