64-65 - C++中的异常处理
创始人
2024-03-03 13:23:02

---- 整理自狄泰软件唐佐林老师课程

1. C++异常处理

1.1 try catch内容一

  • C++内置了异常处理的语法元素 try catch
  • try语句用于处理正常代码逻辑
  • catch语句用于处理异常情况
    • try语句中的异常由对应的catch语句处理

在这里插入图片描述

1.2 C++通过throw语句抛出异常信息

在这里插入图片描述

1.3 C++异常处理分析

  • throw抛出的异常必须被 catch 处理
    • 当前函数 能够处理异常,程序继续往下执行
    • 当前函数 无法处理异常,则函数停止运行,并返回
    • 未被处理的异常 会顺着 函数调用栈 向上传播,直到被处理为止,否则程序将停止执行

在这里插入图片描述

1.4 编程实验:C++异常处理初探

#include 
#include using namespace std;double divide(double a, double b)
{const double delta = 0.000000000000001;double ret = 0;if( !((-delta < b) && (b < delta)) ){ret = a / b;}else{throw 0;}return ret;
}int main(int argc, char *argv[])
{    try{double r = divide(1, 0);cout << "r = " << r << endl;}catch(...){cout << "Divided by zero..." << endl;}return 0;
}

在这里插入图片描述

1.5 try catch内容二

  • 同一个try语句 可以跟上 多个catch语句
    • catch语句可以定义 具体处理的异常类型
    • 不同类型的异常由 不同的catch语句 负责处理
    • try语句中可以抛出 任何类型 的异常
    • catch() 用于处理 所有类型的异常(只能放在最后)
    • 任何异常都 只能被捕获(catch) 一次

1.6 异常处理的匹配规则

在这里插入图片描述

  • 异常处理匹配时,不进行任何的类型转换

1.7 编程实验:异常类型匹配

#include 
#include using namespace std;void Demo1()
{try{   throw 'c';}catch(char c){cout << "catch(char c)" << endl;}catch(short c){cout << "catch(short c)" << endl;}catch(double c){cout << "catch(double c)" << endl;}catch(...){cout << "catch(...)" << endl;}
}void Demo2()
{throw string("D.T.Software");
}int main(int argc, char *argv[])
{    Demo1();try{Demo2();}catch(char* s){cout << "catch(char *s)" << endl;}catch(const char* cs){cout << "catch(const char *cs)" << endl;}catch(string ss){cout << "catch(string ss)" << endl;}return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 字符串相关:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.8 catch语句块中可以抛出异常

在这里插入图片描述

  • 问题:为什么要在catch中 重新 抛出异常?
    • catch中捕获的异常可以被重新解释后抛出
    • 工程开发中使用这样的方式统一异常类型,如下:

在这里插入图片描述

1.9 实验:异常的重新解释

在这里插入图片描述

  • 直接调用第三方库中的函数,得到的异常是 -3,然后去找文档或者是代码中注释或者是分析代码,知道是超时异常,不够直观,效率较低:

在这里插入图片描述

  • 改进后:

在这里插入图片描述

#include 
#include using namespace std;void Demo()
{try{try{throw 'c';}catch(int i){cout << "Inner: catch(int i)" << endl;throw i;}catch(...){cout << "Inner: catch(...)" << endl;throw;}}catch(...){cout << "Outer: catch(...)" << endl;}
}/*假设: 当前的函数式第三方库中的函数,因此,我们无法修改源代码函数名: void func(int i)抛出异常的类型: int-1 ==》 参数异常-2 ==》 运行异常-3 ==》 超时异常
*/
void func(int i)
{if( i < 0 ){throw -1;}if( i > 100 ){throw -2;}if( i == 11 ){throw -3;}cout << "Run func..." << endl;
}void MyFunc(int i)
{try{func(i);}catch(int i){switch(i){case -1:throw "Invalid Parameter";break;case -2:throw "Runtime Exception";break;case -3:throw "Timeout Exception";break;}}
}int main(int argc, char *argv[])
{// Demo();try{MyFunc(11);}catch(const char* cs){cout << "Exception Info: " << cs << endl;}return 0;
}

1.10 异常的类型可以是自定义类类型

  • 对于类类型异常的匹配依旧是至上而下严格匹配
  • 赋值兼容性原则在异常匹配中依然适用
  • 一般而言:
    • 匹配子类异常的catch放在上部
    • 匹配父类异常的catch放在下部
  • 在工程开发中会定义一系列的异常类
  • 每个类代表工程中可能出现的一种异常类型
  • 代码复用时可能需要重新解释不同的异常类
  • 在定义catch语句块时推荐使用引用作为参数

1.11 编程实验:类类型的异常

#include 
#include using namespace std;class Base
{
};class Exception : public Base
{int m_id;string m_desc;
public:Exception(int id, string desc){m_id = id;m_desc = desc;}int id() const{return m_id;}string description() const{return m_desc;}
};/*假设: 当前的函数是第三方库中的函数,因此,我们无法修改源代码函数名: void func(int i)抛出异常的类型: int-1 ==》 参数异常-2 ==》 运行异常-3 ==》 超时异常
*/
void func(int i)
{if( i < 0 ){throw -1;}if( i > 100 ){throw -2;}if( i == 11 ){throw -3;}cout << "Run func..." << endl;
}void MyFunc(int i)
{try{func(i);}catch(int i){switch(i){case -1:throw Exception(-1, "Invalid Parameter");break;case -2:throw Exception(-2, "Runtime Exception");break;case -3:throw Exception(-3, "Timeout Exception");break;}}
}int main(int argc, char *argv[])
{try{MyFunc(11);}catch(const Exception& e){cout << "Exception Info: " << endl;cout << "   ID: " << e.id() << endl;cout << "   Description: " << e.description() << endl;}catch(const Base& e){cout << "catch(const Base& e)" << endl;}return 0;
}

在这里插入图片描述
在这里插入图片描述

1.12 C++标准库中提供了实用异常类族

  • 标准库中的异常都是从 exception类 派生的
  • exception类有两个主要的分支:
    • logic_error:常用语程序中的可避免逻辑错误
    • runtime_error:常用语程序中无法避免的恶性错误

1.13 标准库中的异常

在这里插入图片描述

2. 小结

  • C++中直接支持异常处理的概念
  • try catch是C++中异常处理的专用语句
  • try语句处理正常代码逻辑,catch语句处理异常情况
  • 同一个try语句可以跟上多个catch语句
  • 异常处理必须严格匹配,不尽进行任何的类型转换
  • catch语句块可以抛出异常

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...