C++ 异常处理

2023-11-10

         C++ 异常​(Exception)是指在程序运行时产生的特殊情况,例如,尝试除以零的操作。异常提供了一种转移程序控制权的方式,异常处理涉及到三个关键字:try、catch、throw

  • throw: 当问题出现时,程序会抛出一个异常。这是通过使用 throw 关键字来完成的。
  • catch: 在想要处理问题的地方,通过异常处理程序捕获异常。catch 关键字用于捕获异常。
  • try: try 块中的代码标识将抛出被激活的特定异常,它后面通常跟着一个或多个 catch 块。

         如果有一个块抛出一个异常,捕获异常的方法会使用 try 和 catch 关键字。try 块中放置可能抛出异常的代码,try 块中的代码被称为保护代码

抛出异常

         可以使用 throw 语句在代码块中的任何地方抛出异常,throw 语句的操作数可以是任意的表达式,表达式的结果的类型决定了抛出的异常的类型。以下是尝试除以零时抛出异常的实例:

double division(int a, int b)
{
   if( b == 0 )
   {
      throw "Division by zero condition!";
   }
   return (a/b);
}

捕获异常

         catch 块跟在 try 块后面,用于捕获异常。可以指定想要捕捉的异常类型,这是由 catch 关键字后的括号内的异常声明决定的。 使用 try/catch 语句的语法如下所示:

try
{
   program-statements  // 保护代码
}catch( Exception—declaration ) {
   handler-statements  // 处理 Exception—declaration 异常的代码 
}catch( Exception—declaration ) {
   handler-statements
}catch( Exception—declaration ) {
   handler-statements
}  //...

         下面是一个实例,抛出一个除以零的异常,并在 catch 块中捕获该异常。

#include <iostream>
using namespace std;
 
double division(int a, int b)
{
   if( b == 0 )
   {
      throw "Division by zero condition!";
   }
   return (a/b);
}
 
int main ()
{
   int x = 50;
   int y = 0;
   double z = 0;
 
   try {
     z = division(x, y);
     cout << z << endl;
   }catch (const char* msg) {
     cerr << msg << endl;
   }
 
   return 0;
}

         程序抛出了"Division by zero condition!",一个类型为 const char* 的异常,因此,catch 块中使用 const char*。

         编译和执行上面的代码:

 Division by zero condition!

         若 try 块在不同的情境下会抛出不同的异常时,可以罗列多个 catch 语句,用于捕获不同类型的异常。若让 catch 块能够处理 try 块抛出的任何类型的异常,则必须在异常声明的括号内使用省略号 ...,如下所示:

try
{
  program-statements 
}catch(...) {
  handler-statements
}

标准的异常

         C++ 提供了一系列定义在 <exception> 中,可以在程序中使用的标准的异常,以父子类层次结构组织起来,如下所示:

C++ 异常的层次结构

         每个异常的说明:

异常 描述
std::exception 该异常是所有标准 C++ 异常的父类。
std::bad_alloc 该异常可以通过 new 抛出。
std::bad_cast 该异常可以通过 dynamic_cast 抛出。
std::bad_typeid 该异常可以通过 typeid 抛出。
std::bad_exception 这在处理 C++ 程序中无法预期的异常时非常有用。
std::logic_error 理论上可以通过读取代码来检测到的异常。
std::domain_error 当使用了一个无效的数学域时,会抛出该异常。
std::invalid_argument 当使用了无效的参数时,会抛出该异常。
std::length_error 当创建了太长的 std::string 时,会抛出该异常。
std::out_of_range 该异常可以通过方法抛出,例如 std::vector 和 std::bitset<>::operator[]()。
std::runtime_error 理论上不可以通过读取代码来检测到的异常。
std::overflow_error 当发生数学上溢时,会抛出该异常。
std::range_error 当尝试存储超出范围的值时,会抛出该异常。
std::underflow_error 当发生数学下溢时,会抛出该异常。

定义新的异常

         通过继承和重载 exception 类来定义新的异常。下面的实例演示如何使用 std::exception 类来实现自己的异常:

#include <iostream>
#include <exception>
using namespace std;
 
class MyException : public exception
{
public:
  const char * what() const throw ()   // 成员函数声明后跟上throw(),表示函数不会抛出异常
  { 
    return "C++ Exception";
  }
};
 
int main()
{
  try
  {
    throw MyException();
  } catch(MyException& e) {
    cout << "MyException caught" << endl;
    cout << e.what() << endl;
  } catch(std::exception& e) {
    //其他的错误
  }

  return 0;
}

          what() 是异常类提供的一个公共方法,它已被所有子异常类重载。这将返回异常产生的原因。编译和执行上面的代码:

MyException caught
C++ Exception

          补充: throw() 是异常规格说明,目的是为了让函数使用者知道该函数可能抛出的异常有哪些,可以在throw()函数的参数声明中列出这个函数可能抛掷的所有异常类型。

          在 C++11 中,可以使用关键字 noexcept声明一个函数不会抛出任何异常。

void what() noexcept;

          下面两个函数声明的异常规格在语义上是相同的,都表示函数不抛出任何异常。

void what() throw();
void what() noexcept;

          throw函数后面的意义:

  • 函数后面跟throw(),表示该函数不会抛出异常,函数是异常安全的
  • 函数后面跟throw(...),表示该函数可能会抛出任何形式的异常
  • 函数后面跟throw(exception type),表示该函数只抛出exception type类型的异常

          const在函数后面的意义:

  • 只允许在类的非静态成员函数后面加const(加到非成员函数或静态成员后面会产生编译错误);
  • 后面加的const是对this指针指向的类的对象的修饰,即修饰 *this,所以this所指向的类对象的成员都是不允许被修改的;

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • echart地图合并,并取消边框

    原文地址 https blog csdn net qq 19816325 article details 108520451 问题 echart地图区域合并 并不出现边框 按照之前的经验 每个区域都有自己的json数组 如果要调整区域划分
  • Unity官方FPS教程解析(一)

    在刚接触Unity的时候学习官方教程时下载导入过官方FPS教程 但是由于什么都不懂所以光是看着整个层次面板都觉得难受 所以就放弃了 今天算是重拾并且也算是对一些和我一样的刚接触的各位发表一些自己的见解 那我们开始 一 下载并导入这个FPS资
  • 网站提示:你的连接不是专用连接

    网站提示 你的连接不是专用连接 前言 解决方案 前言 你的连接不是专用连接怎么解决方法如下 如果是使用edge 浏览器 出现 你的连接不是专用连接提示 提示访问非信任CA签发证书的网站时 浏览器都会提示你的连接不是专用连接 且无法进入 解决
  • DC/AC:单相方波全桥逆变电路设计原理及实验仿真

    电压源单向方波逆变电路可以是推挽式或全桥式 而后者的应用更加广泛 桥式电路又分为全桥和半桥 工作原理类似而略有差异 半桥电路较为简单 本文以单相全桥方波逆变电路进行分析 单相全桥逆变电路如图1所示 由一个大小为Ud的直流电压源和两个桥臂组成
  • 电路交换报文交换和分组交换

    http tech sina com cn other 2004 07 15 1604388226 shtml http tech sina com cn other 2004 07 15 1554388215 shtml 网络交换技术共经
  • 蓝桥杯——砝码称重(JAVA)

    题目 你有一架天平和 N个砝码 这 N 个砝码重量依次是 W 1 W 2 W N 请你计算一共可以称出多少种不同的重量 注意砝码可以放在天平两边 输入格式 输入的第一行包含一个整数 N 第二行包含 N 个整数 W 1 W 2 W 3 W N
  • 区块链草莽时代,致敬每一个实干者

    七月在野 八月在宇 九月在户 十月都在裁员 气温一点点降低 区块链行业也一步步临近冰点 区块链进入寒冬 留下的都是实干者 目前 区块链行业发展还存在各种各样的问题 比如人才储备不够 招不到人 法律的普及速度跟不上 技术应用落地还较为困难 而
  • Java程序员要掌握的前端:JavaScript篇

    第一篇HTML CSS在这里哦 Java程序员要掌握的前端 HTML CSS 第二章 Javascript 它是一种脚本语言 可以用来更改页面内容 控制多媒体 制作图像 动画等等 例子 修改页面内容 js 代码位置 引入 js 脚本 注意
  • 如何证明自己会python_如何判断python字符串出现次数?这几种方法你一定要学会...

    摘要 python应用阶段是实际的工作经验 现在如何判断python字符串出现次数 这几种方法你一定要学会 小编建议大家可以试着理解这些内容 也许对您的python学习有帮助 毕竟实践出真知 所以你要知道如何判断python字符串出现次数
  • 哲♂学三幻神带你学习ConstraintLayout(约束布局)

    哲 学三幻神带你学习ConstraintLayout 约束布局 标签 空格分隔 Tutorial Android ConstraintLayout 是什么 ConstraintLayout 约束布局 其实已经不算什么新东西了 很多同学应该知
  • 解决Gitlab不能向master分支push、merge的问题

    今天在向gitlab push代码的时候出现 remote rejected master gt master pre receive hook declined 这是因为gitlab默认开启了分支保护 以保护master分支不被其他用户随
  • 二、C语言初阶:函数

    2 函数 2 1 函数原型 函数原型通常放在头文件里面或者调用它的函数的前面 include
  • 从零开始学习Blazor

    什么是Blazor Blazor的优势和用途 简介 Blazor是一种基于WebAssembly的开源框架 它允许开发人员使用C 语言编写Web应用程序 Blazor可以在浏览器中运行C 代码 而无需使用JavaScript 该框架由微软开
  • 前端js循环修改对象属性,得到新数组数据属性是最后一个数(深拷贝与浅拷贝)

    项目场景 在前端项目的开发中 我将JSON格式的对象数组 例如 a 1 b 2 引入js文件 在js文件中通过循环修改对象数组中的数据 然后把新的数据push添加到新建数组中 这一过程涉及深拷贝与浅拷贝的问题 困扰了一下午 总算是解决了 特
  • HDMI PL驱动开发记录

    在Zynq UltraScale example的基础上 舍弃掉在PS端做驱动的方案 在PS端搭建工程 并利用串口进行配置 对于多路HDMI的不同输入输出控制起来较为方便 且利用PL来做驱动 结构更加清晰 在做HDMI驱动的时候要了解两个重
  • 回归模型的变量筛选与预测

    我眼中的回归变量筛选 变量筛选是回归建模过程关键的一步 由于变量间的相关性 必然会导致不同的筛选方法得到不同的模型 在所有变量筛选方法中 向前法 向后法以及逐步回归法的使用频率较高 因为这类方法操作简单 运算速度快 非常实用 这种方法选出的
  • java获取url锚点_定位与锚点

    文档流 普通流 上至下 左至右 浮动流 元素添加了float 定位流 添加了定位属性 定位 position static 默认值 absolute 绝对定位 脱离文档流 不占位 默认参考浏览器零点 relative 相对定位 占据文档流
  • c# 得到list符合某条件的索引值,排序

    请教 在List集合中怎么得到元素的索引值 参考 http www myexception cn c sharp 385022 html 这个可以用来读取窗口的多个textbox控件中内容 1 解决方案 2 你可以使用FindIndex方法
  • Centos8 部署 Mysql8.0及主从复制

    1 拉取镜像 root VM 24 9 centos docker pull mysql 如需拉取置指定版本镜像加上 版本号即可 root VM 24 9 centos docker pull mysql 7 6 1 创建本地文件用于挂载
  • C++ 异常处理

    C 异常 Exception 是指在程序运行时产生的特殊情况 例如 尝试除以零的操作 异常提供了一种转移程序控制权的方式 异常处理涉及到三个关键字 try catch throw throw 当问题出现时 程序会抛出一个异常 这是通过使用