STL学习笔记——auto_ptr
2012-11-27 21:03
344 查看
auto_ptr是智能型指针的一种。auto_ptr主要作用是防止程序出现异常时出现内存泄露:
当程序正常运行到结束的时候,指针ptr可以完美的被销毁。但是我们经常忘记在函数结束时添加delete。更麻烦的是,如果程序在执行到delete之前出现异常,程序根本就不会执行到delete,于是出现了内存泄露。当然是用catch可以解决问题,但是为每一个对象增加一个catch并不是一个好的idea。
智能型指针auto_ptr销毁时,同时回收其所指向的资源。由于auto_ptr就是一个局部变量,当其所在函数结束时(无论正常或异常),它就一定会被销毁。
可以这样理解,auto_ptr拥有它所指向的对象。所以,当身为对象拥有者的auto_ptr被销毁时,其对象也将被销毁。需要注意的是:一个对象只能被一个auto_ptr拥有,严禁一物二主。
使用auto_ptr改写上边的例子:
注意:auto_ptr不允许使用一般指针的赋值初始化方式,必须使用数值来初始化:
关于拥有权转移的问题
由于auto_ptr要求一物不能有二主,当对象赋值或copy构造时就要考虑其拥有权的转移问题了。
在copy构造和赋值时将auto_ptr的拥有权转交出去:
赋值时的操作:
智能型指针auto_ptr与普通指针的区别:
copy和赋值不仅仅是简单的复制对象,而是转移了对象的拥有权。对于普通指针,赋值和copy,其右值是不发生任何变化的。
注意:移交了拥有对象之后的auto_ptr将不再拥有任何对象,只剩下一个空空的"NULL"指针,所以应避免对其再次执行提领操作。
只有auto_ptr可以拿来当做另一个auto_ptr的初值,普通指针不可以:
数据的起点和终点
1,如果auto_ptr以值传递的方式当做参数传递给某函数,那么该函数就是数据的终点。此时被调用端的参数获得了这个auto_ptr的拥有权,如果函数在结束时不讲它传递出去,那么该函数退出时它所拥有的对象就将被删除。
2,当一个auto_ptr被返回,其拥有权便被转交给调用端了。函数便是数据的起点:
auto_ptr的缺陷:
auto_ptr包含拥有权,如果无意转移拥有权,就不要再参数列表中使用auto_ptr,也不要把它用作返回值。
看例子:
实际上控制拥有权的转移时完全可以做到的:
错误的auto_ptr运用:
1,auto_ptrs之间不能共享拥有权
还是一物不能拥有二主的问题。
2,并不存在对array的auto_ptrs
auto_ptrs不能指向array,因为auto_ptr是透过delete而非delete[]来释放其所拥有的对象的。
3,auto_ptrs并非放之四海而皆准
这不是一个引用计数型指针,关于引用计数型指针请参考这里
4,auto_ptrs不满足STL容器对元素的要求
void foo() { ClassA* ptr = new ClassA; ... delete ptr; }
当程序正常运行到结束的时候,指针ptr可以完美的被销毁。但是我们经常忘记在函数结束时添加delete。更麻烦的是,如果程序在执行到delete之前出现异常,程序根本就不会执行到delete,于是出现了内存泄露。当然是用catch可以解决问题,但是为每一个对象增加一个catch并不是一个好的idea。
智能型指针auto_ptr销毁时,同时回收其所指向的资源。由于auto_ptr就是一个局部变量,当其所在函数结束时(无论正常或异常),它就一定会被销毁。
可以这样理解,auto_ptr拥有它所指向的对象。所以,当身为对象拥有者的auto_ptr被销毁时,其对象也将被销毁。需要注意的是:一个对象只能被一个auto_ptr拥有,严禁一物二主。
使用auto_ptr改写上边的例子:
#include <memory> void foo() { std::auto_ptr<ClassA>ptr(new ClassA); ... }和普通指针一样,auto_ptr用operate*来提领其所指对象,用operate->来指向对象中的成员。
注意:auto_ptr不允许使用一般指针的赋值初始化方式,必须使用数值来初始化:
std::auto_ptr<ClassA>ptr1(new ClassA);//ok std::auto_ptr<ClassA>ptr2=new ClassA;//error
关于拥有权转移的问题
由于auto_ptr要求一物不能有二主,当对象赋值或copy构造时就要考虑其拥有权的转移问题了。
在copy构造和赋值时将auto_ptr的拥有权转交出去:
std::auto_ptr<ClassA>ptr1(new ClassA); std::auto_ptr<ClassA>ptr2(ptr1);//copy构造函数第一句话执行结束后,ptr1拥有新创建的对象的拥有权。第二句话执行结束后,ptr2接收了ptr1所拥有的对象,ptr1不再拥有新创建的那个对象。
赋值时的操作:
std::auto_ptr<ClassA>ptr1(new ClassA); std::auto_ptr<ClassA>ptr2; ptr2=ptr1;//赋值操作执行结束后,ptr2拥有新创建的那个对象,ptr1不再拥有。如果在赋值之前,ptr2拥有其他的对象,那么赋值时将调用delete删除ptr2所拥有的对象,然后接收新的对象。
智能型指针auto_ptr与普通指针的区别:
copy和赋值不仅仅是简单的复制对象,而是转移了对象的拥有权。对于普通指针,赋值和copy,其右值是不发生任何变化的。
注意:移交了拥有对象之后的auto_ptr将不再拥有任何对象,只剩下一个空空的"NULL"指针,所以应避免对其再次执行提领操作。
只有auto_ptr可以拿来当做另一个auto_ptr的初值,普通指针不可以:
std::auto_ptr<ClassA> ptr; ptr = new ClassA;//error ptr=std::auto_ptr<ClassA>(new ClassA);//ok
数据的起点和终点
1,如果auto_ptr以值传递的方式当做参数传递给某函数,那么该函数就是数据的终点。此时被调用端的参数获得了这个auto_ptr的拥有权,如果函数在结束时不讲它传递出去,那么该函数退出时它所拥有的对象就将被删除。
2,当一个auto_ptr被返回,其拥有权便被转交给调用端了。函数便是数据的起点:
std::auto_ptr <ClassA> foo() { std::auto_ptr<ClassA> ptr(new ClassA); ... return ptr; } void g() { std::auto_ptr<ClassA>p; for(int i=0;i<10;++i) { p=f(); ... } }函数调用结束时,将返回拥有权连同对象。
auto_ptr的缺陷:
auto_ptr包含拥有权,如果无意转移拥有权,就不要再参数列表中使用auto_ptr,也不要把它用作返回值。
看例子:
template<class T> void bad_print(std::auto_ptr<T>p) { if(p->get()==NULL) { std::cout<<"NULL"; }else { std:cout<<*p; } }多么荒唐的一个例子,当打印结束的时候对象也跟着被销毁了,后续操作肿么办呢?可以用constant 引用的方式,向函数传递拥有权,可是,这也十分的危险!(《The C++ Standard Library》是这么说的,此处我灰常不解,望诸位指教!)
实际上控制拥有权的转移时完全可以做到的:
const std::auto_ptr<int> p(new int); *p=42; bad_print(p);//编译将出现错误 *p=18;//okconst的auto_ptr将不能转移其拥有的拥有权,但是可以改变其拥有对象:
std::auto_ptr<int >foo() { const std::auto_ptr<int>p(new int); std::auto_ptr<int>q(new int); *p=42;//ok bad_print(p);//error *p=*q;//ok p=q;//error return p;//error }
错误的auto_ptr运用:
1,auto_ptrs之间不能共享拥有权
还是一物不能拥有二主的问题。
2,并不存在对array的auto_ptrs
auto_ptrs不能指向array,因为auto_ptr是透过delete而非delete[]来释放其所拥有的对象的。
3,auto_ptrs并非放之四海而皆准
这不是一个引用计数型指针,关于引用计数型指针请参考这里
4,auto_ptrs不满足STL容器对元素的要求
相关文章推荐
- C++ Standard Stl -- SGI STL源码学习笔记(01) auto_ptr
- STL学习笔记 ---- 神秘的auto_ptr
- c++ 模板学习笔记:类模板模拟auto_ptr智能指针(权哥)
- effective c++ 学习笔记2----auto_ptr
- 智能指针基础std::auto_ptr与new、delete的重载学习笔记
- STL 源码研读笔记(1)– auto_ptr
- c++ standard library 学习笔记-auto_ptr<T> 注意事项
- STL学习之auto_ptr
- SGI STL 学习笔记二 vector
- Chromium Base学习笔记 —— Weakptr
- STL学习笔记----13.STL算法之 (变序性算法)
- STL学习笔记——序列式容器list
- STL 学习笔记 ( 一. 概述 )
- iOS9-by-Tutorials-学习笔记六:UIStackView-Auto-Layout-Changes
- STL学习笔记-String类
- Automake 学习笔记之一:The Introduction / Example Of GNU Autoconf, Automake And Libtool
- STL学习笔记1
- STL学习笔记1--vector
- C++ Primer 学习笔记_42_STL实践与分析(16)–再谈迭代器【上】
- 黑马程序员---OC学习笔记之autorelease注意及错误用法