通过对VC版本的auto_ptr的源代码得知VC版本还有一点小缺陷,又对VS版本的auto_ptr做了一些剖析,具体代码和注释如下:

 //假设全局pa2都是用pa1来构造
//如:pa2(pa1)、pa2=pa1 template<class _Ty> //auto_ptr类声明
class auto_ptr; template<class _Ty>
struct auto_ptr_ref //auto_ptr的辅助类
{
explicit auto_ptr_ref(_Ty *_Right): _Ref(_Right)
{}
_Ty *_Ref;
}; template<class _Ty>
class auto_ptr//auto_ptr类
{
public:
typedef auto_ptr<_Ty> _Myt; //管理类的类型
typedef _Ty element_type; //被管理元素的类型 explicit auto_ptr(_Ty *_Ptr = ) : _Myptr(_Ptr) //构造
{} //从原始指针中获取控制权 //若pa2(pa1);
auto_ptr(_Myt& _Right) : _Myptr(_Right.release()) //拷贝构造
{} //若:pa2(pa1)
auto_ptr(auto_ptr_ref<_Ty> _Right)
{
// 用右值来构造
_Ty *_Ptr = _Right._Ref; //将pa1的指针保存在Ptr中
_Right._Ref = ; // 将pa1的指针指向空
_Myptr = _Ptr; // 将pa2的地址指向pa1的地址
} template<class _Other>
operator auto_ptr<_Other>() //转换为可转换的类型
{
return (auto_ptr<_Other>(*this));
} template<class _Other>
operator auto_ptr_ref<_Other>() //隐式类型转换,将auto_ptr类型指针转换为auto_ptr_ref类型
{
_Other *_Cvtptr = _Myptr;
auto_ptr_ref<_Other> _Ans(_Cvtptr);
_Myptr = ;
return (_Ans);
} template<class _Other>
_Myt& operator=(auto_ptr<_Other>& _Right) //针对可转换为 _Ty* 类型的 _Other* 类型的拷贝函数
{
reset(_Right.release());
return (*this);
} template<class _Other> //特定类型构造函数
auto_ptr(auto_ptr<_Other>& _Right) : _Myptr(_Right.release())
{} //针对可转换为 _Ty* 类型的 _Other* 类型的构造函数 //若:pa2=pa1
_Myt& operator=(_Myt& _Right) //拷贝赋值函数
{
reset(_Right.release());
return (*this);
} //若:pa2=pa1
_Myt& operator=(auto_ptr_ref<_Ty> _Right) //将一个 auto_ptr_ref 类型的变量赋值给 *this
{
_Ty *_Ptr = _Right._Ref; //将pa1的Ref指针赋值给pa2的_Ptr指针
_Right._Ref = ; // 将pa1的Ref指针指向空
reset(_Ptr); // 将pa2的_Myptr指向pa1
return (*this);
} ~auto_ptr() //析构
{
delete _Myptr; //析构指针所指向的内容
} _Ty& operator*() const //重载*
{
if (_Myptr == )
{
_DEBUG_ERROR("auto_ptr not dereferencable");
}
return (*get());
} _Ty *operator->() const //重载->
{
return (get());
} _Ty *get() const //用来返回_Myptr的地址
{
return (_Myptr);
} _Ty *release() //将一个对象的_Myptr记住,再指向空,然后再把其记住的地址返回
{
_Ty *_Tmp = _Myptr; //先将pa1的指针用Tmp保存,
_Myptr = ; //再讲pa1的指针指向空
return (_Tmp); // 返回Tmp即原来pa1指向的地址
} void reset(_Ty *_Ptr = ) //将this的_Myptr指向传进来的指针的地址
{
if (_Ptr != _Myptr) //如果pa1“以前的”(pa1在release()中被指向空,就是返回的那个Tmp用来记住pa1以前的那个地址)那个地址所指向的地址不等于pa2的地址
delete _Myptr; //先析构pa2所指向的地址 _Myptr = _Ptr; //再将pa2地址指向返回来的pa1的老地址
} private:
_Ty *_Myptr;
};

测试代码:

 int main(int argc, char* argv[])
{
auto_ptr<int> pa(new int());
auto_ptr<int>pa1(pa);
cout << *pa1<<endl;
auto_ptr<int> pa2;
pa2 = pa1;
cout << *pa2 << endl;
auto_ptr_ref<int> par1(new int());
auto_ptr<int> pa3(par1);
cout << *pa3 << endl;
return ;
}

运行结果:

10
10
20

auto_prt的VS版本源码剖析的更多相关文章

  1. auto_ptr的VC版本源码剖析

    auto_ptr是当前C++标准库(STL)中提供的一种智能指针,包含于头文件 #include<memory> .auto_ptr 能够方便的管理单个堆内存对象,在你不用的时候自动帮你释 ...

  2. spring各个版本源码

    各版本源码下载地址 http://maven.springframework.org/release/org/springframework/spring/

  3. Spring各版本源码下载

    spring framework 各版本源码下载地址 现在spring的源码下载地址真是不好找,这次终于找到了.记录一下,以帮助需要的朋友. https://github.com/spring-pro ...

  4. [转帖]nginx1.17.2版本源码安装

    nginx1.17.2版本源码安装 原创: 沧海书生 Ansible爱好者 昨天 公众号里面的内容 这里简单测试了下 在x86的虚拟机里面编译安装 nginx 仅make make install n ...

  5. Kafka 0.10.1版本源码 Idea编译

    Kafka 0.10.1版本源码 Idea编译 1.环境准备 Jdk 1.8 Scala 2.11.12:下载scala-2.11.12.msi并配置环境变量 Gradle 5.6.4: 下载Grad ...

  6. 任务驱动,Winform VS WEB对比式学习.NET开发系列第一篇------身份证解析(不断更新的WEB版本及Winform版本源码)

    一 本系列培训随笔适用人群 1. 软件开发初学者 2. 有志于转向Web开发的Winform程序员 3. 想了解桌面应用开发的Web程序员 二 高效学习编程的办法 1 任务驱动方式学习软件开发 大部分 ...

  7. 网站安全通用防护代码(C#版本源码提供)

    每一个开发者都会意识到,网站发布之前,需要进行安全检查. 那么如何拦截攻击者注入恶意代码?如何防御诸如跨站脚本攻击(XSS).SQL注入攻击等恶意攻击行为? 针对目前常见的一些安全问题,结合目前一些常 ...

  8. spring framework 各版本源码下载地址

    现在spring的源码下载地址真是不好找,这次终于找到了.记录一下,以帮助需要的朋友. https://github.com/spring-projects/spring-framework/tags ...

  9. jquery的2.0.3版本源码系列(6):2880-3042行,回调对象,对函数的统一管理

    目录 1 . 回调对象callbacks的演示 回调的使用有一点像事件绑定,先绑定好,等到有点击事件或者其他时就触发. <script src="js/jquery-2.0.3.js& ...

随机推荐

  1. 0219 springmvc-拦截器和响应增强

    拦截器 拦截器分同步拦截器和异步拦截器: HandlerInterceptor 方法和执行时机 可以看DispathcerServlet的原来确定它的三个方法的执行时机: AsynHandlerInt ...

  2. gtid环境下mysqldump对于set-gtid-purged的取值

    gtid环境备份的时候,还在为set-gtid-purged=0|1的选择而烦恼吗,一起来分析一下. [mysql@lxd-vm1@/home/mysql]$ mysqldump --help | g ...

  3. CentOS 7在执行yum操作时 报错

    CentOS 7在执行yum操作时, 报错:Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=6&arch ...

  4. Prettier - Code formatter使用

    更多VSCode插件使用请访问:VSCode常用插件汇总 Prettier - Code formatter这是一款 格式化js.css代码插件,暂不解释. Prettier是什么? Prettier ...

  5. ctf-ping命令执行绕过

    题目连接:http://ctf.klmyssn.com/challenges#Ping 命令执行绕过,试了试过滤了一些:一些命令 但是反引号可以执行命令 通过拼接,可以拼接出来:ls 命令 127.0 ...

  6. [CQOI2015] 网络吞吐量 - 最大流,最短路

    在第i个点只能选A[i]次的情况下,能选出多少条1-n的最短路 Solution 我们造出最短路DAG,然后对每个点拆点限流,跑最大流即可 双向边警告!(有悖直觉 #include <bits/ ...

  7. 题解 P5613 【[MtOI2019]黑蚊子多】

    题目传送门 一道模拟题目,签到送分题. 您需要的知识 1.while循环 2.for循环 3.一维数组 思路: Step 1:按题目要求,定义a[],n,m,k int a[10001]; int n ...

  8. AE 打开Shp文件

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  9. RMQ(区间最值问题)

    问题: RMQ (Range Minimum/Maximum Query)问题是指:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A中下标在i,j里的最小(大) ...

  10. java web HttpServletRequest

    一.HttpServletRequest介绍 HttpServletRequest 对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,通过这个对象提供的方法,可以获得客户端请求的所有信息. ...