先看下面的代码:

  1. int main()
  2. {
  3. int *i=new int(10);
  4. /*
  5. 这中间的代码出现异常
  6. */
  7. delete i;
  8. return 0;
  9. }

如果出现了这样的情况,动态分配的内存就不会被释放。为了处理这样的问题,可以使用C++标准库auto_ptr类。

如果使用下面的代码,内存就一定会被释放

  1. #include<memory>
  2. int main()
  3. {
  4. std::auto_ptr<int> ptr(new int(10));
  5. /*
  6. 这中间的代码出现异常
  7. */
  8. return 0;
  9. }

auto_ptr类是接受一个类型形参的模板,它为动态分配的对象提供异常安全。auto_ptr类在头文件memory中定义。

  1. auto_ptr<T> ap    创建名为ap的未绑定的auto_ptr对象
  2. auto_ptr<T> ap(p) 创建名为ap的auto_ptr对象,ap拥有指针p指向的对象。该构造函数为explicit
  3. auto_ptr<T> ap1(ap2) 创建名为ap1的auto_ptr对象,ap1保存原来存储在ap2中的指针。ap2将所有权转给ap1,ap2成为未绑定的auto_ptr对象。
  4. ap1=ap2           将所有权转给ap1.删除ap1指向的对象,并使ap1指向ap2指向的对象,使ap2成为未绑定的
  5. *ap               返回ap绑定对象的引用
  6. ap->              返回ap保存的指针
  7. ap.reset(p)       如果p与ap的值不同,则删除ap指向的对象并且将ap绑定到p
  8. ap.release()      返回ap保存的指针并且使ap成为未绑定的
  9. ap.get()          返回ap保存的指针

auto_ptr只能用于管理从new返回的一个对象,它不能管理动态分配的数组。auto_ptr对象在复制和赋值的时候有不同寻常的行为,所以不能将auto_ptr存放到保准库容器类型中。

当auto_ptr对象超出作用域或者被撤销的时候,就会自动释放aotu_ptr保存指针指向对象的内存。

auto_ptr是可以保存任何类型指针的模板

初始化auto_ptr对象的时候,使用如下方法

auto_ptr<int> i(new int(10));

如下初始化是错误的:

auto_ptr<int> i=new int(10);

i所指的由new表达式创建的对象在超出作用域时自动删除。如果i是局部对象,i所指对象在定义i的块的末尾删除;如果发生异常,则i也超出作用域,析构函数将自动运行i的析构函数作为异常处理的一部分;如果i是全局对象,就在程序末尾删除i引用的对象。

如下代码:

auto_ptr<string> ptr(new string("HELLO"));

*ptr="HELLO";   //改变ptr所保存的指针所指对象的内容

string s=*ptr;     //返回ptr所保存指针所指对象

if(ptr->empty())  //判断ptr所指对象是否为空

  1. #include<memory>
  2. #include<iostream>
  3. #include<string>
  4. using namespace std;
  5. int main()
  6. {
  7. std::auto_ptr<string> ptr(new string("HELLO"));
  8. /*
  9. 这中间的代码出现异常,内存照样回收
  10. */
  11. cout<<*ptr<<endl;
  12. string s=*ptr;
  13. *ptr="zhycheng";
  14. cout<<*ptr<<endl<<(ptr->empty())<<endl;
  15. /*
  16. 这中间的代码出现异常,内存照样回收
  17. */
  18. return 0;
  19. }

复制auto_ptr对象的时候,如下

auto_ptr<int> ap1(ap2);

那么ap1将获得ap2所保存指针的管理,ap2将会变为未绑定

如果是赋值的话

ap3=pa2;

将删除ap3保存的指针所指对象

ap3置为ap2所指对象

ap2未绑定

如果不给定初始化式,ptr的值为0,对0指针解引用,程序出错并且没有定义会发生什么事。使用VC++的编译器的情况是程序崩溃。

可以使用ptr.get()获得ptr保存的指针来判断ptr是否绑定。

auto_ptr的reset函数接受一个指针,来改变auto_ptr保存的指针,如果新指针与旧指针不同,则删除旧指针所指对象的空间。相同的话就没什么改变。

auto_ptr要注意如下四点:

1.不要使用auto_ptr对象保存指向静态分配内存对象的指针

2.不要使用两个auto_ptr对象保存同一指针

3.不要使用auto_ptr保存动态分配数组的指针

4.不要将auto_ptr对象存储在容器中

C++ Primer 有感(异常处理)(三)的更多相关文章

  1. C++中的异常处理(三)

    C++中的异常处理(三) 标签: c++C++异常处理 2012-11-24 23:00 1520人阅读 评论(0) 收藏 举报  分类: 编程常识(2)  版权声明:本文为博主原创文章,未经博主允许 ...

  2. C++ Primer 有感(异常处理)

    1.异常是通过抛出对象而引发的.该对象的类型决定应该激活哪个处理代码.被选中的处理代码是调用链中与该对象类型匹配且离抛出异常位置最近的那个. 2.执行throw的时候,不会执行跟在throw后面的语句 ...

  3. C++ Primer 有感(异常处理)(四)

    查看普通函数的声明的时候,不可能知道该函数会抛出什么异常,但是在捕获异常的时候要知道一个函数会抛出什么样的异常,以便捕获异常. 异常说明:指定,如果函数抛出异常,抛出的异常将是包含在该说明中的一种,或 ...

  4. C++ Primer 有感(异常处理)(二)

    异常就是运行时出现的不正常,例如运行时耗尽了内存或遇到意外的非法输入.异常存在于程序的正常功能之外,并要求程序立即处理.不能不处理异常,异常是足够重要的,使程序不能继续正常执行的事件.如果找不到匹配的 ...

  5. C++ Primer 笔记 第三章

    C++ Primer 第三章 标准库类型 3.1using声明 例: using namespace atd; using std::cin; 3.2string类型 初始化方式 string s1 ...

  6. Spring 异常处理三种方式 @ExceptionHandler

    异常处理方式一. @ExceptionHandler 异常处理方式二. 实现HandlerExceptionResolver接口 异常处理方式三. @ControllerAdvice+@Excepti ...

  7. C++ primer的第三章的主要内容

    第三章主要介绍了C++中标准库类型.主要讲到string和vector类型.在string类型中,能够很方便的操作字符串,应该要注意的地方就是它的字符串中元素的位置的类型是:size_type类型的数 ...

  8. 《C++ primer》--第三章

    习题3.2 什么是默认构造函数? 解答: 默认构造函数就是在没有显示提供初始化式时调用的构造函数.它由不带参数的构造函数,或者为所有形参提供默认实参的构造函数定义.如果定义某个类的变量时没有提供初始化 ...

  9. Java中的异常处理(三) - 自定义异常处理

    1.异常处理类 package second; public class MyException extends Exception { MyException (){ } MyException ( ...

随机推荐

  1. spring boot+mybaits+mysql+generato(逆向工程)+前后台数据交互

    如按照我博客上没有弄出来 请在下面留言 我好修改 谢谢 小弟使用的是Eclipse 首先下载STS插件 help--->Elipse Marketplace--->find搜索栏里面搜索S ...

  2. hive升级遇到的几个小问题

    1.hiveserver2正常启动,但是beeline连不上服务. 我的服务是开在本机的,但是用主机名和127好像都不能访问服务了 jdbc:hive2://172.19.1.11:10000> ...

  3. 基于无域故障转移群集 配置高可用SQLServer 2016数据库

    基于上次的文章搭建的环境,可以在这里:http://www.cnblogs.com/DragonStart/p/8275182.html看到上次的文章. 演示环境 1. 配置一览 Key Value ...

  4. 彻底理解Oracle中的集合操作与复合查询

    --Oracle中的复合查询 复合查询:包含集合运算(操作)的查询 常见的集合操作有: union: 两个查询的并集(无重复行.按第一个查询的第一列升序排序) union all:两个查询的并集(有重 ...

  5. Zookeeper核心工作机制(zookeeper特性、zookeeper数据结构、节点类型)

    10.1 zookeeper特性 1.Zookeeper:一个leader,多个follower组成的集群. 2.全局数据一致:每个server保存一份相同的数据副本,client无论连接到哪个ser ...

  6. Hibernate设置时间戳的默认值和更新时间的自动更新

    Generated and default property values 生成的和默认的属性值 The database sometimes generates a property value, ...

  7. leetcode 5 Longest Palindromic Substring--最长回文字符串

    问题描述 Given a string S, find the longest palindromic substring in S. You may assume that the maximum ...

  8. KVO and Swift

    不像Objective-c中的类,Swift类对于KVO并没有原生的支持,不过你可以在类型安全的前提下使用属性观察者轻松的完成相同的目标. 不管如何,从NSObject类派生出的类是支持KVO的,如果 ...

  9. 在android系统上写C语言程序--开机启动该程序不进入安卓系统

    今天要写的这篇博文意义重大,也是网上很少有的,这是在我工作中学会的一项技术,当然,它也是由简单的问题组合而来的.如何在安卓中写C语言程序,调试安卓驱动,测试程序的的一项重要技能,下面我就不说废话了,直 ...

  10. Ubuntu安装telent服务器时出现:apt-get:Package has no installation

    当我在终端敲下这条命令的时候,系统就提示telnetd:apt-get:Package has no installation sudo apt-get install xinetd telnetd ...