auto_ptr基本用法注意点

auto_ptr基本用法注意点1构造函数析构函数auto_ptr在构造时获取对某个对象的所有权(ownership),在析构时释放该对象。我们可以这样使用auto_ptr来提高代码安全性:int p = new int(0);auto_ptr ap(p);从此我们不必关心应该何时释放p, 也不用担心发生异常会有内存泄漏。这里我们有几点要注意:1) 因为auto_ptr析构的时候肯定会删除他所拥有的那个对象,所有我们就要注意了,一个萝卜一个坑,两个auto_ptr不能同时拥有同一个对象。像这样:int p = new int(0);auto_ptr ap1(p);auto_ptr ap2(p);因为ap1与ap2都认为指针p是归它管的,在析构时都试图删除p, 两次删除同一个对象的行为在C++标准中是未定义的。所以我们必须防止这样使用auto_ptr.2) 考虑下面这种用法:int pa = new int[10];auto_ptr ap(pa);因为auto_ptr的析构函数中删除指针用的是delete,而不是delete [],所以我们不应该用auto_ptr来管理一个数组指针。3)构造函数的explicit关键词有效阻止从一个“裸”指针隐式转换成auto_ptr类型。4) 因为C++保证删除一个空指针是安全的, 所以我们没有必要把析构函数写成:~auto_ptr() throw(){if(ap) delete ap;}2 拷贝构造与赋值引用计数智能指针不同的,auto_ptr要求其对“裸”指针的完全占有性。也就是说一个”裸“指针不能同时被两个以上的auto_ptr所拥有。那么,在拷贝构造或赋值操作时,我们必须作特殊的处理来保证这个特性。auto_ptr的做法是“所有权转移”,即拷贝或赋值的源对象将失去对“裸”指针的所有权,所以,与一般拷贝构造函数赋值函数不同, auto_ptr的拷贝构造函数,赋值函数的参数为引用而不是常引用(const reference).当然,一个auto_ptr也不能同时拥有两个以上的“裸”指针,所以,拷贝或赋值的目标对象将先释放其原来所拥有的对象。这里的注意点是:1) 因为一个auto_ptr被拷贝或被赋值后, 其已经失去对原对象的所有权,这个时候,对这个auto_ptr的提领(dereference)操作是不安全的。如下:int p = new int(0);auto_ptr ap1(p);auto_ptr ap2 = ap1;cout << ap1; //错误,此时ap1只剩一个null指针在手了这种情况较为隐蔽的情形出现在将auto_ptr作为函数参数按值传递,因为在函数调用过程中在函数的作用域中会产生一个局部对象来接收传入的auto_ptr(拷贝构造),这样,传入的实参auto_ptr就失去了其对原对象的所有权,而该对象会在函数退出时被局部auto_ptr删除。如下:void f(auto_ptr ap){cout<<ap;}auto_ptr ap1(new int(0));f(ap1);cout << ap1; //错误,经过f(ap1)函数调用,ap1已经不再拥有任何对象了。因为这种情况太隐蔽,太容易出错了, 所以auto_ptr作为函数参数按值传递是一定要避免的。或许大家会想到用auto_ptr的指针或引用作为函数参数或许可以,但是仔细想想,我们并不知道在函数中对传入的auto_ptr做了什么, 如果当中某些操作使其失去了对对象的所有权, 那么这还是可能会导致致命的执行期错误。 也许,用const reference的形式来传递auto_ptr会是一个不错的选择。2)我们可以看到拷贝构造函数与赋值函数都提供了一个成员模板在不覆盖“正统”版本的情况下实现auto_ptr的隐式转换。如我们有以下两个类class base{};class derived: public base{};那么下列代码就可以通过,实现从auto_ptr到auto_ptr的隐式转换,因为derived可以转换成base类型auto_ptr apbase = auto_ptr(new derived);3) 因为auto_ptr不具有值语义(value semantic), 所以auto_ptr不能被用在stl标准容器中。所谓值语义,是指符合以下条件的类型(假设有类A):A a1;A a2(a1);A a3;a3 = a1;那么a2 == a1, a3 == a1很明显,auto_ptr不符合上述条件,而我们知道stl标准容器要用到大量的拷贝赋值操作,并且假设其操作的类型必须符合以上条件。3 提领操作(dereference)提领操作有两个操作, 一个是返回其所拥有的对象的引用, 另一个是则实现了通过auto_ptr调用其所拥有的对象的成员。如:struct A{void f();}auto_ptr apa(new A);(apa).f();apa->f();当然, 我们首先要确保这个智能指针确实拥有某个对象,否则,这个操作的行为即对空指针的提领是未定义的。原文链接: https://www.cnblogs.com/macong/archive/2013/04/20/3032015.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/85379

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月9日 下午10:02
下一篇 2023年2月9日 下午10:02

相关推荐