我们都知道,实现auto_ptr有两种方法:

第一种方法:在上一篇博客中我已经实现了,主要思想是管理权转移。

第二种方法:它是我们c++标准库中以前的一个版本,主要思想是在auto_ptr类中除了有一个指针的成员变量以外还有一个bool类型的成员变量_owner。构造函数中将_owner设为真,表示对象是指针所指向的内存的拥有者,当要赋值时(ap1=ap2),将ap1的_owner置为true,ap2的_owner置为false。

这样我们析构对象时只要检查它的_owner是否为true。为真就释放内存,不为真就不释放。

主要实现如下:

#include<iostream>
using namespace std;
template<class T>
class AutoPtr
{
public:AutoPtr(T* ptr):_ptr(ptr), _owner(true){}~AutoPtr(){if (_owner){delete _ptr;}}AutoPtr(AutoPtr<T>& ap):_ptr(ap._ptr), _owner(true){ap._owner = false;}AutoPtr& operator=(AutoPtr<T>& ap){if (this != &ap){   if (_owner){delete _ptr;}_ptr = ap._ptr;_owner = true;ap._owner = false;}return *this;}T* operator->(){return _ptr;}T& operator*(){return *_ptr;}
private:T* _ptr;bool _owner;
};

看完auto_ptr的实现,有人会问:

看起来这种方法更好些,它实现了可以一般指针的使用方式,可以有多个指针指向同一块内存,并且都可以访问这块内存,而我们知道,新版本的auto_ptr的实现方式(管理权转移)最大的缺点就是不能有几个指针指向同一块内存,一个智能指针只能指向一块内存。

既然旧版本的智能指针实现方式比新版本的要好用,那为什么会被替换呢?

请看下面一段代码:

AutoPtr<int> ap1(new int(1));if (1){AutoPtr<int> ap2(ap1);}*ap1 = 3;

这段代码是用旧版本实现的智能指针(ap1)指向一个动态开辟的内存,然后在if条件语句中又有一个ap2指向这块内存,我们会知道,根据旧版的智能指针的实现原理,ap1的_owner为false,ap2的_owner为true。那么除了if条件语句的局部作用域,ap2就自动调用析构函数释放内存,那么当我们在外面*ap1=3时,访问到的是一块已经被释放了的内存,那么程序这时就会出现问题。

如果是新版的auto_ptr,它提供了一个公有成员函数GetPtr(),可以获取指针_ptr,当发生这种情况时,它可以先判断_ptr是否为空,然后才去访问内存。旧版本这样做是无用的,因为ap1的_ptr并不为空。

转载于:https://blog.51cto.com/haipi/1760289

实现auto_ptr的两种方法相关推荐

  1. SQL Server中灾难时备份结尾日志(Tail of log)的两种方法

    简介 在数据库数据文件因各种原因发生损坏时,如果日志文件没有损坏.可以通过备份结尾日志(Tail of log)使得数据库可以恢复到灾难发生时的状态. 例如: 上图中.在DB_1中做了完整备份,在Lo ...

  2. C++/C++11中用于定义类型别名的两种方法:typedef和using

    类型别名(type alias)是一个名字,它是某种类型的同义词.使用类型别名有很多好处,它让复杂的类型名字变得简单明了.易于理解和使用,还有助于程序员清楚地知道使用该类型的真实目的.在C++中,任何 ...

  3. jquery-12 折叠面板如何实现(两种方法)

    jquery-12 折叠面板如何实现(两种方法) 一.总结 一句话总结:1.根据点击次数来判断显示还是隐藏,用data方法保证每个元素一个点击次数:2.找到元素的下一个,然后toggle实现显示隐藏. ...

  4. java 匿名list,java创造匿名对象的两种方法

    在java中有时候需要一些匿名对象的使用.可能有些小伙伴拿还不会创造,其实我们在学习一些方法时都或多或少的接触过.本篇所要讲到的创造匿名对象总结了两种方法,分别是静态工具方法和Lambda表达式,我们 ...

  5. Android Studio导入Eclipse项目的两种方法

    Android Studio导入Eclipse项目有两种方法,一种是直接把Eclipse项目导入Android Studio,另一种是在Eclipse项目里面进行转换,然后再导入Android Stu ...

  6. Response.Redirect 打开新窗体的两种方法

    普通情况下,Response.Redirect 方法是在server端进行转向,因此,除非使用 Response.Write("<script>window.location=' ...

  7. centos下两种方法安装git

    centos 5 64位下两种方法安装git 这里来给大家介绍下编译安装和yum安装git.   系统:centos 5.5 64位   需要的软件包:git-latest.tar.gz epel-r ...

  8. mysql创建库几种方法_MySQL创建数据库的两种方法

    本文为大家分享了两种mysql创建数据库的方法,供大家参考,具体内容如下 第一种方法:使用 mysqladmin 创建数据库使用普通用户,你可能需要特定的权限来创建或者删除 mysql 数据库. 所以 ...

  9. 牛客 Tree(最小深度总和)(两种方法求重心)难度⭐⭐⭐

    题目链接 牛妹有一张连通图,由n个点和n-1条边构成,也就是说这是一棵树,牛妹可以任意选择一个点为根,根的深度deprootdep_{root}deproot​​为0,对于任意一个非根的点,我们将他到 ...

最新文章

  1. 图像转文字(分类识别等),文字转图片,实际需要的过程
  2. Spring Boot——基于spring-boot-starter-mail发送邮件的 Service 服务类DEMO
  3. linux添加删除回环地址,CentOS7如何添加本地回环地址?CentOS7添加本地回环地址的方法...
  4. Tapioca:linux上同gtalk语音通信
  5. wps改照片底色有红边_入学攻略丨证件照的三种换底色方式,你知道了吗?
  6. 搭建SpringMVC详解
  7. 在电子政务项目中如何应付长官意识和拖沓的工作作风?
  8. easyui酷黑风格主题模板组件html
  9. 如何查计算机的网络速度,电脑怎么查网速?教你精准测速的方法
  10. 一文了解DataStore(Preferences)
  11. java实现支付宝网页扫码支付
  12. 压缩文件并删除源文件
  13. My SQL 安装配置
  14. 青岛科技大学和青岛大学计算机专业,青岛科技大学和青岛大学企业管理专业哪个比较好考...
  15. 零基础入门 Vue3 | 附高清原图
  16. 【转】IOS数据库操作SQLite3使用详解
  17. stm32的简易小项目之震动感应灯
  18. QQ群空间登录网址:http://qun.qq.com/air/#
  19. pathlib库使用手册
  20. 视频教程-springboot+Vue整合前后端分离权限后台管理系统-Java

热门文章

  1. 计算机科学与技术与cs,CSgo! | 遇见CS—带你走进传说中的计算机专业
  2. android 通知显示时间,android:在特定时间显示通知?
  3. 线性回归损失函数为什么要用平方形式
  4. U-net结构及代码注释
  5. 【阿里云课程】图像翻译GAN结构与应用
  6. 性能测试四十八:Jenkins+Ant+Jmeter系统部署
  7. C语言 - sizeof和strlen的区别
  8. linux 下 iscsi的简单使用
  9. @JsonIgnoreProperties转换实体时忽略json中不存在的字段
  10. idea 提示忽略大小写