C++ 高级篇(三)—— 出错处理



本节介绍的出错处理是ANSI-C++ 标准引入的新功能。如果你使用的C++ 编译器不兼容这个标准,则你可能无法使用这些功能。

在编程过程中,很多时候我们是无法确定一段代码是否总是能够正常工作的,或者因为程序访问了并不存在的资源,或者由于一些变量超出了预期的范围,等等。

这些情况我们统称为出错(例外),C++ 新近引入的三种操作符能够帮助我们处理这些出错情况: try, throw 和 catch 。

它们的一般用法是:

	try {// code to be triedthrow exception;}catch (type  exception){// code to be executed in case of exception}

它们所进行的操作是:

  • try 语句块中的代码被正常执行。如果有例外发生,代码必须使用关键字throw 和一个参数来扔出一个例外。这个参数可以是任何有效的数据类型,它的类型反映了例外的特征。
  • 如果有例外发生,也就是说在try 语句块中有一个throw 指令被执行了,则catch 语句块会被执行,用来接收throw传来的例外参数。

例如:

    // exceptions#include <iostream.h>int main () {char myarray[10];try {for (int n=0; n<=10; n++) {if (n>9) throw "Out of range";myarray[n]='z';}} catch (char * str) {cout << "Exception: " << str << endl;}return 0;}   
Exception: Out of range

在这个例子中,如果在n 循环中,n 变的大于9 了,则仍出一个例外,因为数组 myarray[n] 在这种情况下会指向一个无效的内存地址。当throw 被执行的时候,try 语句块立即被停止执行,在try 语句块中生成的所有对象会被销毁。此后,控制权被传递给相应的catch 语句块(上面的例子中即执行仅有的一个catch)。最后程序紧跟着catch 语句块继续向下执行,在上面的例子中就是执行 return 0;.

throw 语法与 return 相似,只是参数不需要扩在括号。

catch 语句块必须紧跟着try 语句块后面,中间不能有其它的代码。catch 捕获的参数可以是任何有效的数据类型。catch 甚至可以被重载以便能够接受不同类型的参数。在这种情况下被执行catch 语句块是相应的符合被throw扔出的参数类型的那一个:

    // exceptions: multiple catch blocks#include <iostream.h>int main () {try {char * mystring;mystring = new char [10];if (mystring == NULL) throw "Allocation failure";for (int n=0; n<=100; n++) {if (n>9) throw n;mystring[n]='z';}} catch (int i) {cout << "Exception: ";cout << "index " << i << " is out of range" << endl;} catch (char * str) {cout << "Exception: " << str << endl;}return 0;}    
Exception: index 10 is out of range

在上面的例子中,有两种不同的例外可能发生:

  1. 如果要求的10个字符空间不能够被赋值(这种情况很少,但是有可能发生):这种情况下扔出的例外会被catch (char * str)捕获。
  2. n超过了mystring的最大索引值(index):这种情况下扔出的例外将被catch (int i)捕获,因为它的参数是一个整型值。

我们还可以定义一个catch 语句块来捕获所有的例外,不论扔出的是什么类型的参数。这种情况我们需要在catch 或面的括号中写三个点来代替原来的参数类型和名称,如:

   try {// code here}catch (...) {cout << "Exception occurred";}

try-catch 也是可以被嵌套使用的。在这种情况下,我们可以使用表达式throw;(不带参数)将里面的catch 语句块捕获的例外传递到外面一层,例如:

   try {try {// code here}catch (int n) {throw;}}catch (...) {cout << "Exception occurred";}

没有捕获的例外 (Exceptions not caught)

如果由于没有对应的类型,一个例外没有被任何catch 语句捕获,特殊函数terminate 将被调用。

这个函数通常已被定义了,以便立即结束当前的进程(process),并显示一个“非正常结束”( "Abnormal termination")的出错信息。它的格式是:

void terminate();  

标准例外 (Standard exceptions)

一些C++ 标准语言库中的函数也会扔出一些列外,我们可以用try 语句来捕获它们。这些例外扔出的参数都是std::exception 引申出的子类类型的。这个类(std::exception) 被定义在C++ 标准头文件 中,用来作为exceptions标准结构的模型:

因为这是一个类结构,如果你包括了一个catch 语句块使用地址(reference)来捕获这个结构中的任意一种列外 (也就是说在类型后面加地址符 &),你同时可以捕获所有引申类的例外 (C++的继承原则)。

下面的例子中,一个类型为 bad_typeid 的例外(exception的引申类),在要求类型信息的对象为一个空指针的时候被捕获:

    // standard exceptions#include <iostream.h>#include <exception>#include <typeinfo>class A {virtual void f() {}; };int main () {try {A * a = NULL;typeid (*a);} catch (std::exception& e) {cout << "Exception: " << e.what();}return 0;}			
Exception: Attempted typeid of NULL pointer

本节介绍的出错处理是ANSI-C++ 标准引入的新功能。如果你使用的C++ 编译器不兼容这个标准,则你可能无法使用这些功能。

在编程过程中,很多时候我们是无法确定一段代码是否总是能够正常工作的,或者因为程序访问了并不存在的资源,或者由于一些变量超出了预期的范围,等等。

这些情况我们统称为出错(例外),C++ 新近引入的三种操作符能够帮助我们处理这些出错情况: try, throw 和 catch 。

它们的一般用法是:

	try {// code to be triedthrow exception;}catch (type  exception){// code to be executed in case of exception}

它们所进行的操作是:

  • try 语句块中的代码被正常执行。如果有例外发生,代码必须使用关键字throw 和一个参数来扔出一个例外。这个参数可以是任何有效的数据类型,它的类型反映了例外的特征。
  • 如果有例外发生,也就是说在try 语句块中有一个throw 指令被执行了,则catch 语句块会被执行,用来接收throw传来的例外参数。

例如:

    // exceptions#include <iostream.h>int main () {char myarray[10];try {for (int n=0; n<=10; n++) {if (n>9) throw "Out of range";myarray[n]='z';}} catch (char * str) {cout << "Exception: " << str << endl;}return 0;}   
Exception: Out of range

在这个例子中,如果在n 循环中,n 变的大于9 了,则仍出一个例外,因为数组 myarray[n] 在这种情况下会指向一个无效的内存地址。当throw 被执行的时候,try 语句块立即被停止执行,在try 语句块中生成的所有对象会被销毁。此后,控制权被传递给相应的catch 语句块(上面的例子中即执行仅有的一个catch)。最后程序紧跟着catch 语句块继续向下执行,在上面的例子中就是执行 return 0;.

throw 语法与 return 相似,只是参数不需要扩在括号。

catch 语句块必须紧跟着try 语句块后面,中间不能有其它的代码。catch 捕获的参数可以是任何有效的数据类型。catch 甚至可以被重载以便能够接受不同类型的参数。在这种情况下被执行catch 语句块是相应的符合被throw扔出的参数类型的那一个:

    // exceptions: multiple catch blocks#include <iostream.h>int main () {try {char * mystring;mystring = new char [10];if (mystring == NULL) throw "Allocation failure";for (int n=0; n<=100; n++) {if (n>9) throw n;mystring[n]='z';}} catch (int i) {cout << "Exception: ";cout << "index " << i << " is out of range" << endl;} catch (char * str) {cout << "Exception: " << str << endl;}return 0;}    
Exception: index 10 is out of range

在上面的例子中,有两种不同的例外可能发生:

  1. 如果要求的10个字符空间不能够被赋值(这种情况很少,但是有可能发生):这种情况下扔出的例外会被catch (char * str)捕获。
  2. n超过了mystring的最大索引值(index):这种情况下扔出的例外将被catch (int i)捕获,因为它的参数是一个整型值。

我们还可以定义一个catch 语句块来捕获所有的例外,不论扔出的是什么类型的参数。这种情况我们需要在catch 或面的括号中写三个点来代替原来的参数类型和名称,如:

   try {// code here}catch (...) {cout << "Exception occurred";}

try-catch 也是可以被嵌套使用的。在这种情况下,我们可以使用表达式throw;(不带参数)将里面的catch 语句块捕获的例外传递到外面一层,例如:

   try {try {// code here}catch (int n) {throw;}}catch (...) {cout << "Exception occurred";}

没有捕获的例外 (Exceptions not caught)

如果由于没有对应的类型,一个例外没有被任何catch 语句捕获,特殊函数terminate 将被调用。

这个函数通常已被定义了,以便立即结束当前的进程(process),并显示一个“非正常结束”( "Abnormal termination")的出错信息。它的格式是:

void terminate(); 

标准例外 (Standard exceptions)

一些C++ 标准语言库中的函数也会扔出一些列外,我们可以用try 语句来捕获它们。这些例外扔出的参数都是std::exception 引申出的子类类型的。这个类(std::exception) 被定义在C++ 标准头文件 中,用来作为exceptions标准结构的模型:

因为这是一个类结构,如果你包括了一个catch 语句块使用地址(reference)来捕获这个结构中的任意一种列外 (也就是说在类型后面加地址符 &),你同时可以捕获所有引申类的例外 (C++的继承原则)。

下面的例子中,一个类型为 bad_typeid 的例外(exception的引申类),在要求类型信息的对象为一个空指针的时候被捕获:

    // standard exceptions#include <iostream.h>#include <exception>#include <typeinfo>class A {virtual void f() {}; };int main () {try {A * a = NULL;typeid (*a);} catch (std::exception& e) {cout << "Exception: " << e.what();}return 0;}			
Exception: Attempted typeid of NULL pointer

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/401817.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ 高级篇(一)—— 模板(Templates)

模板(Templates)是ANSI-C 标准中新引入的概念。如果你使用的 C 编译器不符合这个标准&#xff0c;则你很可能不能使用模板。 函数模板( Function templates) 模板(Templates)使得我们可以生成通用的函数&#xff0c;这些函数能够接受任意数据类型的参数&#xff0c;可返回任意类…

PPT到底是天使还是魔鬼?

说老实话&#xff0c;我非常不喜欢那些PPT的培训者一味地鼓吹PPT的重要性&#xff0c;视觉化思维的重要性&#xff0c;PPT在演讲中的重要性等等&#xff0c;我很清楚他们这么说是因为他们必须这么说&#xff0c;因为如果不把PPT的重要性强调一下&#xff0c;谁来上他的课呢&…

ultraedit正则表达式

一般使用ultraedit中的Perl风格的正则表达式&#xff0c;下面是perl正则的基本语法 perl中的元字符如下&#xff1a; ^ 表示一行的开头&#xff1b; $ 表示一行的结尾&#xff1b; ( ) 表示一个匹配块的&#xff0c;可以对匹配上的块通过$1,$2...进行读取&#xff0c;…

微软云介绍

微软云介绍 http://msdn.microsoft.com/zh-cn/ff380142 什么是云开发&#xff1f;&#xff08;概述&#xff09; 云计算是指远程运行并通过 Internet 访问的计算机和应用程序。在云计算中&#xff0c;虚拟机在大型数据中心中运行&#xff0c;并取代了物理 PC 和服务器。通过将许…

IO端口和IO内存的区别及分别使用的函数接口

IO端口和IO内存的区别及分别使用的函数接口 每个外设都是通过读写其寄存器来控制的。外设寄存器也称为I/O端口&#xff0c;通常包括&#xff1a;控制寄存器、状态寄存器和数据寄存器三大类。根据访问外设寄存器的不同方式&#xff0c;可以把CPU分成两大类。一类CPU&#xff08…

Win8 HTML5与JS编程学习笔记(二)

近期一直受到win8应用的Grid布局困扰&#xff0c;经过了半下午加半个晚上的奋斗&#xff0c;终于是弄明白了Grid布局方法的规则。之前我是阅读的微软官方的开发教程&#xff0c;书中没有详细说明CSS3的布局规则&#xff0c;自己鼓捣了半天也是一头雾水&#xff0c;于是又找到了…

Windows下的Qt Creator的安装

采用Qt和Qt creator分别下载和安装的方式&#xff1a;&#xff08;需要手动设置关联Qt和Qt Creator&#xff09; 一、软件下载 从http://qt-project.org/downloads分别下载Qt和Qt Creator&#xff1a; Qt使用4.7.2版本&#xff1a;qt-win-opensource-4.7.2-mingw.exe Qt Creato…

进程 、进程组、会话、控制终端之间的关系

一个进程组可以包含多个进程 进程组中的这些进程之间不是孤立的&#xff0c;他们彼此之间或者存在者父子、兄弟关系&#xff0c;或者在功能有相近的联系。 那linux为什么要有进程组呢&#xff1f;其实提供进程组就是方便管理这些进程。假设要完成一个任务&#xff0c;需要同时并…

Angularjs 通过asp.net web api认证登录

Angularjs 通过asp.net web api认证登录 Angularjs利用asp.net mvc提供的asp.net identity&#xff0c;membership实现居于数据库的用户名/密码的认证登录 环境 Vs.net 2013 Asp.net mvc web api Individual user accounts Angularjs Underscore 新建一个asp.net mvc web api …

PANIC: Unreachable code reached.

为什么80%的码农都做不了架构师&#xff1f;>>> Caused by: java.lang.RuntimeException: PANIC: Unreachable code reached.at cryptix.jce.provider.cipher.BlockCipher.engineGetParameters(BlockCipher.java:244)at javax.crypto.Cipher.checkCryptoPerm(Ciphe…

[LeetCode Online Judge]系列-求二维平面内在一条直线上的最大点数

2019独角兽企业重金招聘Python工程师标准>>> Max Points on a Line Given n points on a 2D plane, find the maximum number of points that lie on the same straight line. 题目是:在2D平面内给N个点,求最多多少个点在一个直线上. 以下是AC的解决方式: /*** Defi…

【思科】GNS3模拟静态NAT/动态NAT

实验拓扑&#xff1a;实验目的&#xff1a;利用NAT技术&#xff0c;使C1,C2能与R2连通。实验步骤&#xff1a;如图配置好IP地址&#xff0c;为C1,C2指定网关192.168.1.1。2.在R1上配置静态NAT.假定为C1配置公网地址12.0.0.3&#xff0c;来实现与R2的连通。这样&#xff0c;静态…

xml 解析

2019独角兽企业重金招聘Python工程师标准>>> 各大数据接口大全&#xff1a;http://blog.sina.com.cn/s/articlelist_2127818045_10_1.html package com.test.junit; import static org.junit.Assert.*; import java.io.ByteArrayInputStream;import java.io.InputSt…

理解Lucene/Solr的缓存

缓存对于提高搜索引擎的吞吐量&#xff0c;降低CPU占用率极为重要。Lucene/Solr在这块做了很多的工作。Lucene/Solr中默认提供了5种缓存&#xff0c;同时solr还提供扩展缓存接口&#xff0c;允许开发者自定义缓存。1 缓存的基本原理Solr实现了两种策略的缓存&#xff1a;LRU(Le…

深入了解tcmalloc(一):windows环境下无缝拦截技术初探

2019独角兽企业重金招聘Python工程师标准>>> 概述&#xff1a; 又到了一个总结提炼的阶段&#xff0c;这次想具体聊聊游戏引擎中使用的内存管理模块tcmalloc组件的使用心得。项目的前期曾经遇到过内存瓶颈&#xff0c;特别是windows系统下的客户端程序在经历长时间运…

删除数据库日志文件的方法

原文:删除数据库日志文件的方法你曾经有在执行SQL的时候&#xff0c;数据库报事务日志已满&#xff0c;然后执行报错。然后纠结于怎么删除数据库日志&#xff0c;捣鼓半天吗&#xff0c;现在就提供两种删除日志文件的方法&#xff0c;希望能够帮到你&#xff01; 阅读目录 方法…

Android屏幕大小适配问题解决

&#xfeff;一、一些基本概念 1、长度&#xff08;真实长度&#xff09;&#xff1a;英寸、inch 2、分辨率&#xff1a;density 每英寸像素数 dpi&#xff08;密度&#xff09; 3、像素&#xff1a;px 4、dip的公式&#xff1a;px /dipdpi/160 所以 dip 类似于英寸、长度&am…

开源 免费 java CMS - FreeCMS1.9 会员组管理

2019独角兽企业重金招聘Python工程师标准>>> 项目地址&#xff1a;http://www.freeteam.cn/ 会员组管理 会员组分为两种&#xff0c;一级是经验会员组&#xff0c;一种是特殊会员组。 经验会员组的会员会根据经验自动变更&#xff0c;特殊会员组不会自动变更&…

蓝桥杯历年预赛习题

标题&#xff1a;啤酒和饮料 啤酒每罐2.3元&#xff0c;饮料每罐1.9元。小明买了若干啤酒和饮料&#xff0c;一共花了82.3元。 我们还知道他买的啤酒比饮料的数量少&#xff0c;请你计算他买了几罐啤酒。 注意&#xff1a;答案是一个整数。请通过浏览器提交答案。 不要书…

产品经理,你来自江湖

2019独角兽企业重金招聘Python工程师标准>>> 产品经理&#xff0c;你来自江湖 ----论产品经理的发展中的技能与技能图书 导读&#xff1a; 过去的15年中&#xff0c;在互联网行业&#xff0c;我认为没有一个职位比产品经理对行业的推动更大&#xff0c;这些年里&…