智能指针auto_ptr介绍
我们大家都知道,new一定要和delete配合使用,但是有一种情况可能会使这种配对失效,如下程序:
#include <iostream>
using namespace std;
class normal_pointer_example
{
public:normal_pointer_example(){cout<<"构造函数执行!\n";}~normal_pointer_example(){cout<<"析构函数执行!\n";}
};
class normal_pointer_wrong{};//normal_pointer_wrong异常
bool quit;
void quit_func()
{if(quit==true)cout<<"调用quit_func函数!\n";throw normal_pointer_wrong();
}
int main()
{try{normal_pointer_example *Npointer=new normal_pointer_example;quit=true;quit_func();delete Npointer;}catch (normal_pointer_wrong){cout<<"输出normal_pointer_wrong异常!!\n";}return 0;
}
该程序的输出结果为:
注意上面这个输出,我们看到当程序全部执行完了都没有能够调用析构函数将对象析构掉!这就说明并没有把对象delete掉!!这个就是问题,因为这样就有可能产生不易察觉的内存泄露。
针对上面这个情况,我们就要使用智能指针类auto_ptr来避免这种情况出现。们来看一个auto_ptr类的声明:
1 template<class _Ty> 2 class auto_ptr 3 { // wrap an object pointer to ensure destruction 4 public: 5 typedef _Ty element_type; 6 7 explicit auto_ptr(_Ty *_Ptr = 0) _THROW0() 8 : _Myptr(_Ptr) 9 { // construct from object pointer 10 } 11 12 auto_ptr(auto_ptr<_Ty>& _Right) _THROW0() 13 : _Myptr(_Right.release()) 14 { // construct by assuming pointer from _Right auto_ptr 15 } 16 17 auto_ptr(auto_ptr_ref<_Ty> _Right) _THROW0() 18 { // construct by assuming pointer from _Right auto_ptr_ref 19 _Ty *_Ptr = _Right._Ref; 20 _Right._Ref = 0; // release old 21 _Myptr = _Ptr; // reset this 22 } 23 24 template<class _Other> 25 operator auto_ptr<_Other>() _THROW0() 26 { // convert to compatible auto_ptr 27 return (auto_ptr<_Other>(*this)); 28 } 29 30 template<class _Other> 31 operator auto_ptr_ref<_Other>() _THROW0() 32 { // convert to compatible auto_ptr_ref 33 _Other *_Cvtptr = _Myptr; // test implicit conversion 34 auto_ptr_ref<_Other> _Ans(_Cvtptr); 35 _Myptr = 0; // pass ownership to auto_ptr_ref 36 return (_Ans); 37 } 38 39 40 template<class _Other> 41 auto_ptr<_Ty>& operator=(auto_ptr<_Other>& _Right) _THROW0() 42 { // assign compatible _Right (assume pointer) 43 reset(_Right.release()); 44 return (*this); 45 } 46 47 template<class _Other> 48 auto_ptr(auto_ptr<_Other>& _Right) _THROW0() 49 : _Myptr(_Right.release()) 50 { // construct by assuming pointer from _Right 51 } 52 53 auto_ptr<_Ty>& operator=(auto_ptr<_Ty>& _Right) _THROW0() 54 { // assign compatible _Right (assume pointer) 55 reset(_Right.release()); 56 return (*this); 57 } 58 59 auto_ptr<_Ty>& operator=(auto_ptr_ref<_Ty> _Right) _THROW0() 60 { // assign compatible _Right._Ref (assume pointer) 61 _Ty *_Ptr = _Right._Ref; 62 _Right._Ref = 0; // release old 63 reset(_Ptr); // set new 64 return (*this); 65 } 66 67 ~auto_ptr() 68 { // destroy the object 69 delete _Myptr; 70 } 71 72 _Ty& operator*() const _THROW0() 73 { // return designated value 74 75 #if _HAS_ITERATOR_DEBUGGING 76 if (_Myptr == 0) 77 _DEBUG_ERROR("auto_ptr not dereferencable"); 78 #endif /* _HAS_ITERATOR_DEBUGGING */ 79 80 __analysis_assume(_Myptr); 81 82 return (*get()); 83 } 84 85 _Ty *operator->() const _THROW0() 86 { // return pointer to class object 87 88 #if _HAS_ITERATOR_DEBUGGING 89 if (_Myptr == 0) 90 _DEBUG_ERROR("auto_ptr not dereferencable"); 91 #endif /* _HAS_ITERATOR_DEBUGGING */ 92 93 return (get()); 94 } 95 96 _Ty *get() const _THROW0() 97 { // return wrapped pointer 98 return (_Myptr); 99 }100 101 _Ty *release() _THROW0()102 { // return wrapped pointer and give up ownership103 _Ty *_Tmp = _Myptr;104 _Myptr = 0;105 return (_Tmp);106 }107 108 void reset(_Ty* _Ptr = 0)109 { // destroy designated object and store new pointer110 if (_Ptr != _Myptr)111 delete _Myptr;112 _Myptr = _Ptr;113 }114 115 private:116 _Ty *_Myptr; // the wrapped object pointer117 };118 _STD_END
从上面这个定义就可以看出来,定义个智能指针就相当于创建了一个auto_ptr类的对象。现在我们再来看看这个类的析构函数:
~auto_ptr()
{ // destroy the objectdelete _Myptr;
}
这里我们就可以看到,由于在私有数据成员中定义了一个模板指针:
_Ty *_Myptr;
所以说在上面的析构函数里面,当我们删除_Myptr指针的时候,其实就是调用delete删除_Myptr所指向的内存块。所以每当我们定义一个智能指针,就是定义了一个auto_ptr类的对象,如:
auto_ptr<string> p (new string);
这句话就定义了一个auto_ptr类的对象p,尖括号里面的string用了初始化它的模板成员_Ty的类型。那么这里面,只要auto_ptr对象存在,它指向的字符串就存在,同理,如果auto_ptr对象不存在,会利用auto_ptr类中的析构函数自动销毁它所指向的字符串,也就避免了内存泄露。
好了,下面我们来用智能指针重写上面的程序,看看会有什么结果。
#include <iostream>
#include <memory>
using namespace std;
class normal_pointer_example
{
public:normal_pointer_example(){cout<<"构造函数执行!\n";}~normal_pointer_example(){cout<<"析构函数执行!\n";}
};
class normal_pointer_wrong{};//normal_pointer_wrong异常
bool quit;
void quit_func()
{if(quit==true)cout<<"调用quit_func函数!\n";throw normal_pointer_wrong();
}
int main()
{try{auto_ptr<normal_pointer_example> Apointer (new normal_pointer_example);quit=true;quit_func();//delete Npointer;}catch (normal_pointer_wrong){cout<<"输出normal_pointer_wrong异常!!\n";}return 0;
}
首先需要注意的是,要调用auto_ptr智能指针,必须包含头文件<memory>。另外,程序的输出:
看到没有,这样一来,析构函数就执行咯~~
转载于:https://www.cnblogs.com/uniqueliu/archive/2011/08/16/2141383.html
智能指针auto_ptr介绍相关推荐
- C++的智能指针auto_ptr、unique_ptr源码解析
C++的智能指针auto_ptr.unique_ptr源码解析 1.前言 2.源码准备 3.源码解析 3.1.auto_ptr解析 3.2.unique_ptr解 3.3.unique_ptr的一个偏 ...
- c++系列 —— 智能指针auto_ptr和unique_ptr
往期地址: c++系列一 -- c++的封装 c++系列二 -- c++的继承 c++系列三 -- 继承和多态特性 c++系列四 -- 运算符重载 c++系列五 -- 静态成员和静态类 c++系列六 ...
- c++中的smart pointer四个智能指针简单介绍
C++里面的四个智能指针: auto_ptr, shared_ptr, weak_ptr, unique_ptr 其中后三个是c++11支持,并且第一个已经被11弃用. 为什么要使用智能指针: 智能指 ...
- C++——智能指针——auto_ptr、shared_ptr、unique_ptr
1.4.智能指针 智能指针是行为类似于指针的类对象. C++11 中提供了三种智能指针,使用这些智能指针时需要引用头文件 : ·shared_ptr; ·unique_ptr; ·auto_ptr; ...
- 模拟实现智能指针auto_ptr,scoped_ptr,shared_ptr
智能指针,顾名思义它是一个聪明的指针,那么到底聪明到哪了呢,让我们一起来看以下的代码. void test1() //内存泄露 {int *p = new int(1);if (1){//...ret ...
- C++智能指针简单介绍
STL一共给我们提供了四种智能指针:auto_ptr.unique_ptr.shared_ptr和weak_ptr(本文章暂不讨论). 模板auto_ptr是C++98提供的解决方案,C+11已将将其 ...
- 智能指针——auto_ptr
1. 开篇 C++里面的四个智能指针:auto_ptr.unique_ptr.shared_ptr.weak_ptr,其中后三个是C++11支持,而这个auto_ptr已经被C++11弃用.但auto ...
- C++ -- 智能指针 auto_ptr,unique_ptr,shared_ptr的简单实现和原理
一,为什么需要智能指针 智能指针是一种预防型的内存泄漏的解决方案.由于C++没有垃圾回收器机制,所以每次new出来的资源都需要手动的delete,如果没有手动释放,就会造成资源泄漏等问题.因此,为了避 ...
- android 的 sp 智能指针用法介绍 sp wp
1原理 Android中定义了两种智能指针类型,一种是强指针sp(strong pointer),另外一种是弱指针(weak pointer). 其实称之为强引用和弱引用更合适一些.强指针与一般意义的 ...
最新文章
- 网站服务器部署注意事项,服务器部署改云部署注意事项
- Oracle Database 快捷版 安装 连接
- mysql 移植 azure_初码-Azure系列-记一次MySQL数据库向Azure的迁移
- Python基础day02【if结构、if elif 结构、while循环、for循环、Break和continue、Debug 调试、三目运算、循环 else 结构】
- 手写自己的MyBatis框架-V2.0结果集处理
- 一线大厂为什么对免费的开源项目这么热衷?
- 怎么样把c语言转变为汇编语言,如何把汇编语言转换成C语言
- vSphere 7 Kubernetes 初体验
- 2021-03-14Java大数据Week2
- spring-boot设置静态文件路径
- python由编译器将源程序转化为机器语言、然后执行_高级语言程序设计(Python)-中国大学mooc-车万翔-车万翔...
- 尚学堂马士兵Oracle教程笔记
- 2017微软校园招聘笔试题
- 董明珠接连直播背后:格力的线上焦虑
- 如何将PPT输出为高精度的图片
- 函数式编程对象Either
- jar包太大?手把手教你分析 Maven 依赖,完成瘦身优化!
- Pytorch 深度学习入门与实践 第二章 pytorch快速入门 (1)
- Collectors.reducing总结
- 关于网站504问题排查