C++:异常的处理

                  6.4 异常处理
程序中常见的错误分为两大类:编译时期的错误和运行时期的错误。

编译时期的错误比较简单容易发现:主要是语法错误,如关键字拼写错误、缺分号、括号不匹配等
运行时期的错误比较难发现,甚至是不可预料的:如算法出错、内存空间不足、角标越界、文件无法打开等

处理异常有两种方式:传统的异常处理方法、系统异常处理机制。

传统异常处理方法特点:是采用判断和分支语句类实现,适合满足小型的应用程序。
系统异常处理机制特点:通过检测、抛出并捕获异常来实现,适合各种大型应用程序

//例6.10  传统的异常处理方法举例

#include<iostream>
using namespace std;
inline int DIV(int x,int y);
int main()
{
 cout<<"7/3="<<DIV(7,3)<<endl;
 cout<<"5/0="<<DIV(5,0)<<endl;
 return 0;
}
inline int DIV(int x,int y)
{
 if(y==0)
  {
    cout<<"除数为0,错误!"<<endl;
    exit(0);
  }
 return x/y;
}

6.4.2 异常处理的方法
C++处理异常的办法是:如果在执行一个函数过程中出现异常,可以不在本函数中立即处理,而是发出一个信息,传给它的上一级(即调用函数)来解决,如果上一级也不能处理,就再传其上一级,由上一级处理,如此逐级上传,如果到最高一级还无法处理,运行系统一般会自动调用系统函数terminate,由它调用abort终止程序。

这样的处理方法使得异常的引发和处理机制分离,而不是有同一个函数完成。这样的做法的好处是使底层函数(被调用函数)着重用于解决实际任务,而不必过多的考虑对异常的处理,以减轻底层函数的负担,而把处理异常的任务移到上层去处理。

C++处理异常的机制是由检查、抛出和捕获3个部分组成,分别由3中语句来完成;try(检查)、
throw(抛出)、catch(捕获)

1.异常的抛出
抛出异常使用throw语句,其格式如下:
throw 表达式;

如果在某段程序中发现了异常,就可以使用throw语句来抛出异常给调用者,该异常由与之匹配的catch语句来捕获。throw语句中的"表达式”是可以抛出的异常类型,异常类型由表达式的类型来表示。例如上例中的异常处理:

inline int DIV(int x,int y)
     {
       if(y==0)
         throw y;            //抛出异常,当除数为0时,语句throw将抛出int型异常
       return x/y;
     } 

     由于变量y的类型是int型,所以当除数为0时语句throw将抛出int型异常

2.异常的检查与捕获
异常的检查try语句与捕获catch语句的格式如下:

try
    {
      被检查的复合语句
    }
    catch(异常类型声明 1)
    {
      进行异常处理的复合语句 1
    }
    catch(异常类型声明 2)
    {
      进行异常处理的复合语句 2
    }
    ......
    catch(异常类型声明 n)
    {
      进行异常处理的复合语句 n
    }

例如上述例子的异常检查与捕获:

try                                       //检查异常
    {
       cout<<"7/3="<<DIV(7,3)<<endl;          //被检查的复合语句
       cout<<"5/0="<<DIV(5,0)<<endl;
    }
    catch(int)                                  //捕获异常,异常类型为int类型
    {
       cout<<"除数为0,错误!"<<endl;           //进行异常处理的复合语句
    }  

//例6.11 处理除数为0异常的程序。

#include<iostream>
using namespace std;
inline int DIV(int x,int y);
int main()
{
 try
 {
  cout<<"7/3="<<DIV(7,3)<<endl;
  cout<<"5/0="<<DIV(5,0)<<endl;
 }
 catch(int i)
 {
  cout<<"i="<<i<<endl;
  cout<<"除数为0,错误!"<<endl;
  cout<<"over\n";
 }
 return 0;
}
inline int DIV(int x,int y)
{
 if(y==0)
   throw y;
 return x/y;
}

程序运行结果是:
7/3=2
除数为0,错误!
over

在本例中,进行异常处理的方法如下:
(1)首先将需要检查,也是容易引起异常的语句或程序段放在try块的花括号中。
(2)如果在执行try语句块内的复合语句过程中没有发生异常,则catch子句不起作用,继续转到catch子句后面的语句继续进行。

(3)如果在执行try块内的复合语句(或被调用函数)过程中发生异常,则throw语句抛出一个异常信息。

(4)throw抛出的异常信息传到try_catch结构,系统寻找与之匹配的catch子句。
(5)执行异常处理语句后,程序继续执行catch子句后的语句。

说明:
(1)被检测的语句或程序段必须放在try块中,否则不起作用。
(2)try和catch块中必须有用花括号括起来的复合语句,即使花括号内只有一个语句也不能省略花括号。
(3)一个try_catch结构中只能有一个try块,但却可以有多个catch块,以便与不同的异常信息匹配。catch后面的括号中,一般只写异常信息的类型名。

(4)如果在catch语句中没有指定异常信息的类型,而是采用了三点删节点"...",则表示它可以捕获任何类型的异常信息。

(5)在某种情况下,在throw语句中可以不包括表达式,如;throw;此时它将当前正在处理的异常信息再次抛出,给起上一层的catch块处理。

(6)C++中,一旦抛出一个异常,而程序又不捕获的话,那么系统就调用系统函数terminate,由它调用abort终止程序。

//例6.12 有多个catch块的异常处理程序。

#include<iostream>
using namespace std;
int main()
{
 double a=2.3;
 try
 {
  throw a;
 }
 catch(int)
 {
  cout<<"异常发生!整数型!"<<endl;
 }
 catch(double)
 {
  cout<<"异常发生!双精度型!"<<endl;
 }
 cout<<"end"<<endl;
 return 0;
}

/*
程序运行结果是:
异常发生!双精度型!
end
*/

//例 6.13 有删节点的异常处理程序。

#include<iostream>
using namespace std;
void func(int x)
{
 if(x)
   throw x;
}
int main()
{
 try
 {
  func(5);
  cout<<"No here!"<<endl;
 }
 catch(...)
 {
  cout<<"异常发生!任意类型!"<<endl;
 }
 cout<<"end"<<endl;
 return 0;
}
/*
程序运行结果是:
异常发生!任意类型!
end
*/ 
时间: 2024-12-16 19:11:46

C++:异常的处理的相关文章

使用 IDEA 创建 Maven Web 项目 (异常)- Disconnected from the target VM, address: &#39;127.0.0.1:59770&#39;, transport: &#39;socket&#39;

运行环境: JDK 版本:1.8 Maven 版本:apache-maven-3.3.3 IDEA 版本:14 maven-jetty-plugin 配置: <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <configuration> <webAppSourceDirectory>${pro

mybaits非配置原因,导致SqlSession was not registered for synchronization异常

今天运行程序时报了 SqlSession [[email protected]] was not registered for synchronization because synchronization is not active [11:03:17]-Closing non transactional SqlSession [[email protected]] 由于异常是集中处理的,所以报了这样的错误,查了半天,网上结果都是说配置文件出错的,可是我的项目配置文件肯定是没错的,因为项目都开

异常笔记--java编程思想

开一个新的系列,主要记一些琐碎的重要的知识点,把书读薄才是目的...特点: 代码少,概念多... 1. 基本概念 异常是在当前环境下无法获得必要的信息来解决这个问题,所以就需要从当前环境跳出,就是抛出异常.抛出异常后发生的几件事: 1.在堆上创建异常对象. 2.当前的执行路径中止                                          3. 当前环境抛出异常对象的引用.                                         4. 异常处理机制接

爱上MVC~业务层刻意抛出异常,全局异常的捕获它并按格式返回

对于业务层的程序的致命错误,我们一直的做法就是直接抛出指定的异常,让程序去终断,这种做法是对的,因为如果一个业务出现了致命的阻塞的问题,就没有必要再向上一层一层的返回了,但这时有个问题,直接抛异常,意味着服务器直接500了,前端如何去显示,或者如果你是API的服务,如果为前端返回,如果是500,那直接就挂了,哈哈! 下面是在MVC环境下优化的全局异常捕获代码(非API) /// <summary> /// 全局异常捕获 /// </summary> public class Glo

Laravel 5.4 中的异常处理器和HTTP异常处理实例教程

错误和异常是处理程序开发中不可回避的议题,在本地开发中我们往往希望能捕获程序抛出的异常并将其显示打印出来,以便直观的知道程序在哪里出了问题并予以解决,而在线上环境我们不希望将程序错误或异常显示在浏览器中(出于安全考虑),这个时候我们仍然要捕获异常,只不过不是显示到浏览器中,而是记录到日志中,方便日后排查问题. 百牛信息技术bainiu.ltd整理发布于博客园 Laravel当然支持PHP原生的错误和异常处理,但是在此基础上进行了一些封装处理,从而更方便在不同开发环境切换以及对错误和异常的处理.

Java必知必会:异常机制详解

一.Java异常概述 在Java中,所有的事件都能由类描述,Java中的异常就是由java.lang包下的异常类描述的. 1.Throwable(可抛出):异常类的最终父类,它有两个子类,Error与Exception. Throwable中常用方法有: getCause():返回抛出异常的原因.如果 cause 不存在或未知,则返回 null. getMeage():返回异常的消息信息. printStackTrace():对象的堆栈跟踪输出至错误输出流,作为字段 System.err 的值.

python 异常和弹出框

import tkinter.messagebox try: fileContent = open("abnormal.txt") fileContent.close() print("over") #把异常消息赋予一个"ex"变量 except Exception as ex: print(ex) tkinter.messagebox.showinfo("Alert",ex) tkinter.messagebox.askye

python基础--接口与归一化设计、封装、异常、网络编程

1 接口与归一化设计 1.1 归一化概念: 归一化的好处: 1.归一化让使用者无需关心对象的类是什么,只需要知道这些对象都具备某些功能就可以了,这极大降低了使用者的使用难度. 2.归一化使得高层的外部使用者可以不加区分的处理所有接口兼容的对象集合 继承的两种用途 一:继承基类的方法,并且做出自己改变或者扩展(代码重用):实践中,继承的这种用途意义并不很大,甚至常常是有害的.因为它使得子类与基类出现强耦合. 二:声明某个子类兼容于某基类,定义一个接口类(模仿java的Interface),接口类中

异常上报工具:腾讯Bugly

1.腾讯出了一个和umeng差不多的异常上报工具Bugly.(传送门:https://bugly.qq.com/docs/) (1)两者比较明显的区别是,Bugly能比较实时上报异常信息,经过测试基本上几秒就能在后台看到上报的信息,umeng的要等一段时间:(这个是我选择Bugly的主要原因) (2)Bugly感觉比较轻盈,主要方向就是异常上报:umeng感觉比较臃肿,主要方向在后台数据统计上:(个人感觉) 2.Cocos的接入文档就在里面,提供了c++/lua/js三种方式的接入,很简单方便就

最近遇到的异常与错误总结

异常 NumberFormatException  数字格式化异常 ArithmeticException 算术异常 ArrayIndexOutOfBoundsException  数组超出绑定异常:没有输入参数,或输入的参数不够 NullPointerException 空指针异常:使用了未实例化的对象 NoSuchMethodError:main  找不到主方法 ClassCastExeption:A 类转换异常 IllegalThreadStateException:非法的线程状态异常 I