zl程序教程

您现在的位置是:首页 >  后端

当前栏目

异常处理简介

异常 处理 简介
2023-09-27 14:27:31 时间

一个程序的功能是有限的,那些超出函数正常功能范围的行为称为异常,最常见的异常包括数据库连接断开、遇到意外输入。异常实际是系统中最难设计的一部分。

一、throw表达式

程序异常检测部分使用throw表达式引发一个异常。throw后的表达式类型就是异常类型,来看一个最简单的类型:

void printAge(int age)
{
  if(age<0)
    throw std::runtime_error("Age < 0");
  std::cout<<"age"<<age<<std::endl;
}
int main()
{
	printAge(-22);
}

运行结果如下:

terminate called after throwing an instance of 'std::runtime_error'
  what():  Age < 0
Aborted (core dumped)

这就是一个典型的意外输入的例子。异常的类型是throw后表达式类型,std::runtime_error是一个标准异常。这个函数在遇到一个负数年龄输入时将会抛出异常,抛出异常意味着:

  • 终止当前函数
  • 将控制权转移给能处理异常的代码

那么标准异常是什么意思呢?标准异常是标准库用于报告标准库函数遇到的问题,用户代码也可以使用这些异常来处理异常,标准异常分别定义在四个头文件中:

  • exception头文件定义了最通用的异常类exception,它只报告异常的发生,不提供额外信息;
  • stdexcept头文件定义了几种常见的异常类,见表1;
  • new头文件定义了bad_alloc异常类型;
  • type_info 定义了bad_cast异常类型;
表1 stdexcept头文件定义的异常
异常名称含义
exception最常见的问题
runtime_error只有运行时才能检测出的问题
range_error运行时错误,生成的结果超出了有意义的至于范围
overflow_error运行时错误,上溢
underflow_error运行时错误,下溢
logic_error程序逻辑错误
domain_error逻辑错误:参数对应结果值不存在
invalid_argument逻辑错误:无效参数
length_error逻辑错误:试图创建一个超出该类型最大长度的对象
out_of_range逻辑错误:试图使用一个超出有效范围的值

标准异常只定义了几种运算,包括创建或拷贝异常类型对象,以及异常类型对象赋值;只能使用默认初始化的方式初始化exception、bad_alloc和bad_cast,不允许为这些对象提供初值;其他异常类型的行为则必须使用string对象或C-style字符串类型初始化对象。

异常类型只定义了一个名为what的成员函数,该函数没有任何参数,返回值是一个指向C-style类型指向常量字符串指针,其目的是为了提供异常的文本信息,what返回值内容与异常对象有关,如果定义了初始值那么返回这个字符串,如果没有,那么由编译器决定。

二、try语句块

语法结构如下:

try{
	program-statements;
}catch(exception-declaration){
	handler-statements;
}catch(exception-declaration){
	handler-statements;
}//...

一个try后面跟着语句块,N个catch子句块。catch子句块包含三个部分:关键字catch、括号内一个对象(可能未命名)声明(称为异常声明,exception declaration)以及一个块,try语句组成程序正常逻辑,try内部的语句声明在块外是无法访问的,就算是catch也不行。还是前面那个例子:

void printAge(int age)
{
  try{
    if(age<0)
      throw std::runtime_error("Age < 0");
    std::cout<<"age"<<age<<std::endl;
  }catch(std::runtime_error e) {
      std::cout<<e.what();
  }
}