我所熟悉的C++智能指针auto_ptr vs shared_ptr (一)
来源:互联网 发布:算法导论 豆瓣 编辑:程序博客网 时间:2024/06/05 11:48
在开发过程中,曾经使用过两种C++的智能指针:auto_ptr和shared_ptr,如今,便总结一下,顺便比较比较二者使用中的区别,注意避免入坑的危险。:-D
(一)auto_ptr
它是C++标准库提供的一种智能指针,在构造时获取某个对象的所有权,在析构时,释放该对象。
如下例所示,即为auto_ptr的使用规则:RAII(Resource Acquisition Is Initialization),也称为“资源获取就是初始化”,
是C++语言的一种管理资源、避免泄漏的惯用法。
C++标准保证任何情况下,已构造的对象最终会销毁,即它的析构函数最终会被调用。
简单的说,RAII 的做法是使用一个对象,在其构造时获取资源,
在对象生命期控制对资源的访问使之始终保持有效,
最后在对象析构的时候释放资源。
int *p = new int(10);std::auto_ptr <int> ap(p);但是使用auto_ptr,有一些必须注意的问题:
(1)不可以将两个或两个以上的auto_ptr指向同一个对象,因为其中当其中一个auto_ptr的生命期结束时,它就会析构对象,而另一个auto_ptr在析构时,将造成多重析构问题,这是很不安全的内存操作。故而,以下的行为是一定要避免的:
int *p = new int(0);auto_ptr<int> ap1(p);auto_ptr<int> ap2(p);//ap1和ap2都指向一个对象,这就是极危险的,必须防止这么使用
(2)不可使用auto_ptr来管理数组指针。
因为auto_ptr在析构时,使用的是delete,而不是delete[]。所以以下的使用方式是绝对要避免的。
int *pa = new int[10];auto_ptr<int> ap(pa);//这种写法是完全错误的,极可能引起内存泄露的危险(3)auto_ptr强调对“裸”指针的完全占有性。也就是说,一个“裸”指针不能同时被两个以上的“裸”指针所拥有。那么,在拷贝构造函数和赋值中,auto_ptr均采取了“所有权转移”的策略,即原指针将失去对裸指针的所有权。
int *p = new int(10);auto_ptr<int> ap1(p);auto_ptr<int> ap2 = ap1; //这会使得ap1变成了NULLcout << *ap1 <<endl; //错误!此时,对其解引用是不安全的。
如上的错误相对而言,比较容易避免,但是对于以下的代码,错误就较难发现。
void fun(auto_ptr<int> ap){ cout << *ap << endl;}auto_ptr<int> ap(new int(0) ) ;fun(ap);cout << *ap << endl; //错误!对空指针的解引用
上述情况比较隐蔽,这是因为在函数调用时,传参引起了拷贝构造函数的调用,所以原来的指针失去了其所有权。
(4)auto_ptr不具备值语义,所以auto_ptr不能被用在STL容器中。
所谓值语义:使之符合以下条件的类型,设有类 Obj:
Obj a;Obj b(a);Obj c;c = a;那么a == b, a == c显然,auto_ptr并不具有这个特点。
auto_ptr用法要点:
1. 需要包含头文件<memory>。
2. Constructor:explicit auto_ptr(X* p = 0) throw(); 将指针p交给auto_ptr对象托管。
3. Copy constructor:auto_ptr(const auto_ptr&) throw(); template<class Y> auto_ptr(const auto_ptr<Y>& a) throw(); 指针的托管权会发生转移。
4. Destructor: ~auto_ptr(); 释放指针p指向的空间。
5. 提供了两个成员函数 X* get() const throw(); //返回保存的指针
6. 对象中仍保留指针 X* release() const throw(); //返回保存的指针,对象中不保留指针
auto_ptr实现关键点:
1. 利用特点“栈上对象在离开作用范围时会自动析构”。
2. 对于动态分配的内存,其作用范围是程序员手动控制的,这给程序员带来了方便但也不可避免疏忽造成的内存泄漏,毕竟只有编译器是最可靠的。
3. auto_ptr通过在栈上构建一个对象a,对象a中wrap了动态分配内存的指针p,所有对指针p的操作都转为对对象a的操作。而在a的析构函数中会自动释放p的空间,而该析构函数是编译器自动调用的,无需程序员操心。
后面的两点引用于http://blog.csdn.net/monkey_d_meng/article/details/5901392,谢谢作者的耐心讲解!
- 我所熟悉的C++智能指针auto_ptr vs shared_ptr (一)
- 我所熟悉的C++智能指针auto_ptr vs shared_ptr (二)
- 【C++】智能指针auto_ptr/unique_ptr/shared_ptr/weak_ptr!!!
- c++智能指针的使用,auto_ptr,shared_ptr
- C++常用的智能指针auto_ptr、shared_ptr
- 智能指针:auto_ptr和shared_ptr
- 智能指针(auto_ptr 和 shared_ptr)
- 智能指针(auto_ptr 和 shared_ptr)
- 智能指针(auto_ptr 和 shared_ptr)
- 智能指针(auto_ptr 和 shared_ptr)
- 智能指针(auto_ptr 和 shared_ptr)
- 智能指针(auto_ptr 和 shared_ptr)
- 智能指针(auto_ptr 和 shared_ptr)
- 智能指针(auto_ptr 和 shared_ptr)
- 智能指针(auto_ptr 和 shared_ptr)
- c++智能指针:auto_ptr shared_ptr
- c++智能指针:auto_ptr shared_ptr
- C++中的资源管理(一):构造自己的auto_ptr与shared_ptr智能指针
- Android 开源框架Universal-Image-Loader完全解析(一)--- 基本介绍及使用
- spring boot 打包成jar 包在发布到服务器上
- 硬件_1bit为什么等于6db
- 软件测试基础课程学习笔记4--测试用例设计方法技巧
- android 常用技术博文
- 我所熟悉的C++智能指针auto_ptr vs shared_ptr (一)
- PHPExcel导出表格
- 浅析Java中CountDownLatch用法
- 用Memcache解决数据库高并发访问的瓶颈问题
- 关于reset.css的疑问:为什么一定要重置浏览器样式?
- C++ STL 总结
- Clojure语言十四 常用宏
- Github上的andoird开源组件整理
- android主线程访问网络的方法