29.C++- 异常处理
C++内置了异常处理的语法元素 try catch
try语句处理正常代码逻辑
- 当try语句发现异常时,则通过throw语句抛出异常,并退出try语句
catch语句处理异常情况
- 当throw语句抛出异常时,则会直接跳到catch语句处理
- catch语句允许被重载,在try语句后面可以有多个catch语句
- 不同类型的异常由不同的catch语句捕获,顺序从上往下严格匹配,不会进行隐式转换,比如:
throw ; //由int型的catch语句捕获
throw 1.5; //由double型的catch语句捕获
throw 1.5f; //由float型的catch语句捕获
throw 'A'; //由char型的catch语句捕获
throw "ABC"; //由char const *型的catch语句捕获
throw string("ABC"); //由string型的catch语句捕获
- cath(...)语句,表示捕获前面所有没被定义的异常,且只能放在所有catch语句的末尾,比如:
try
{
throw 1.55; //直接退出try语句,跳转到满足条件的catch语句
throw "ERR";
}
catch(int i) //只捕获int型异常
{
cout<<i<<endl;
}
catch(string s) //只捕获string型异常
{
cout<<s<<endl;
}
catch(...) //捕获前面所有没被定义的异常
{
cout<<"cath(...)"<<endl;
}
运行打印:
cath(...)
throw抛出的异常必须被catch处理
如果throw抛出的异常,在当前函数没有catch语句能捕获,则会返回到上一级函数里再寻找catch语句,直到被处理为止,否则程序将结束运行,如下图:

在catch语句块中可以将捕获的异常重新抛出
catch抛出的异常,则需要通过外层的try...catch...捕获
如果是catch(...)语句,则直接填throw;即可,编译器会自动将捕获的异常重新抛出
比如:
void internal()
{
try
{
throw ;
}
catch(...)
{
cout<< "internal: catch(...)"<<endl;
throw;
}
} int main()
{ try
{
internal();
} catch(int i)
{
switch(i)
{
case : //1对应超时
cout<<"timeout"<<endl; break;
case : //2对应实参有误
cout<<"invalid argument"<<endl; break;
case : //3对应运行异常
cout<<"runtime exception"<<endl; break;
}
}
return ; }
运行打印:
internal: catch(...)
timeout
catch中重新抛出异常的意义
举个例子,当我们调用第三方库的func()函数,但是该func()函数返回的异常是int型,每个异常值意义大有不同 (每次查看异常值都需要翻看文档手册才行)
所以我们可以在自己库创建一个myfunc()函数,通过try...catch...再次封装func()函数,将异常值重新解释为其它类型(比如const char *),然后再次抛出.
以后调用myfunc()函数,获取的异常信息就是const char *类型了.
如果catch中抛出的类型是类的情况
- 需要将捕获子类异常的catch放在上部
- 将捕获父类异常的cath放在下部, 避免子类异常当做父类异常来使用.
比如:
#include <iostream>
#include <string>
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 < )
{
throw -;
}
if( i > )
{
throw -;
}
if( i == )
{
throw -;
} cout << "Run func..." << endl;
} void MyFunc(int i)
{
try
{
func(i);
} catch(int i)
{
switch(i)
{
case -:
throw Exception(-, "Invalid Parameter"); //生成一个子类对象,并抛出
break; case -:
throw Exception(-, "Runtime Exception");
break; case -:
throw Exception(-, "Timeout Exception");
break;
}
}
} int main(int argc, char *argv[])
{
try
{
MyFunc();
} catch(const Exception& e) //捕获子类异常的catch放在上部
{
cout << "Exception Info: " << endl;
cout << " ID: " << e.id() << endl;
cout << " Description: " << e.description() << endl;
} catch(const Base& e) //捕获父类异常的catch放在下部
{
cout << "catch(const Base& e)" << endl;
}
return ;
}
运行打印:
Exception Info:
ID: -
Description: Timeout Exception
在C++标准库中提供了异常类
头文件 : <stdexcept>
标准库中的异常都是从exception类派生的
exception类主要有两个分支
- logic_error
用于程序中可避免的逻辑错误,在程序运行之前,就能被检测到
logic_error类派生了以下几种类:
- domain_error(const string& ) : 专业领域内的范畴
- invalid_argument(const string& ) : 无效参数,比如对unsigned型进行负数操作
- length_error(const string& ) : 长度异常,比如字符串附加太多字符
- out_of_range(const string&) : 超出范围,比如数组下标越界
- 它们都有一个what()成员函数,用来返回一个字符串异常信息
-runtime_error
常用于程序中无法避免的恶性错误,只在程序运行时才能被检测到
logic_error类派生了以下几种类:
- range_error(const string& ) :内部计算时发生区间错误
- overflow_error(const string& ) :算数运算时发生上溢
- underflow_error(const string& ) :算数运算时发生下溢
- 它们都有一个what()成员函数,用来返回一个字符串异常信息
比如:
#include <iostream>
#include <stdexcept>
using namespace std; template <typename T, int N >
class Array
{
T ma[N];public:
Array()
{
for(int i=;i<N;i++)
ma[N]=;
} T& operator [] (int index)
{
if((index>=)&&(index<N))
{
return ma[index];
} else //数组下标越界
{
throw out_of_range("T& operator [] (int index)"); //抛出一个 out_of_range类
}
}
}; int main()
{
try
{
Array<int,> arr;
arr[]=;
}
catch(out_of_range& exc)
{
cout<< exc.what()<<endl; //打印捕获到out_of_range类的异常信息
cout<< " Line: " << __LINE__ <<", Function: "<< __FUNCTION__ << endl; //打印当前行
}
return ;
}
运行打印:
T& operator [] (int index)
Line: , Function: main
29.C++- 异常处理的更多相关文章
- Java综合高级篇
1.你用过哪些集合类? 大公司最喜欢问的Java集合类面试题 40个Java集合面试问题和答案 java.util.Collections 是一个包装类.它包含有各种有关集合操作的静态多态方法. ja ...
- C++异常处理的编程方法(阿愚,整整29集)
相遇篇 <第1集 初次与异常处理编程相邂逅> <第2集 C++中异常处理的游戏规则> <第3集 C++中catch(…)如何使用> <第4集 C++的异常处理 ...
- Python 29 异常处理, 元类
所学内容 异常处理(常用) AttributeError ·························· 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性xIOError ··· ...
- 29.2 Iterator 迭代器ConcurrentModificationException:并发修改异常处理
/** Iterator:迭代器* * 需求:判断集合中是否包含元素java,如果有则添加元素android * Exception in thread "main" java.u ...
- Spring AOP实例——异常处理和记录程序执行时间
实例简介: 这个实例主要用于在一个系统的所有方法执行过程中出线异常时,把异常信息都记录下来,另外记录每个方法的执行时间. 用两个业务逻辑来说明上述功能,这两个业务逻辑首先使用Spring AOP的自动 ...
- 七天学会ASP.NET MVC (六)——线程问题、异常处理、自定义URL
本节又带了一些常用的,却很难理解的问题,本节从文件上传功能的实现引出了线程使用,介绍了线程饥饿的解决方法,异常处理方法,了解RouteTable自定义路径 . 系列文章 七天学会ASP.NET MVC ...
- Java异常处理和设计
在程序设计中,进行异常处理是非常关键和重要的一部分.一个程序的异常处理框架的好坏直接影响到整个项目的代码质量以及后期维护成本和难度.试想一下,如果一个项目从头到尾没有考虑过异常处理,当程序出错从哪里寻 ...
- Atitit 跨平台异常处理(2)--------异常转换 -----java c# js异常对象结构比较and转换
Atitit 跨平台异常处理(2)--------异常转换 -----java c# js异常对象结构比较and转换 { "@type":"java.lang.Runti ...
- Java7的异常处理新特性-addSuppressed()方法等
开发人员对异常处理的try-catch-finally语句块都比较熟悉.如果在try语句块中抛出了异常,在控制权转移到调用栈上一层代码之前,finally语句块中的语句也会执行.但是finally语句 ...
随机推荐
- Linux时间戳转换成BCD码(转载)
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <math.h> / ...
- phantomjs的安装和使用链接
1.先下载phantomjs并解压2.将phantomjs的bin目录配置到环境变量中3.测试phantomjs,cmd下输入phantomjs进入 (按 Ctrl + c 组 合键退出和 phant ...
- java与eclipse的工作小结
1.Eclipse 的启动画面 A.加启动参数.如: eclipse.exe -showsplash C:/splash.bmp 更多可参考:http://www.cnblogs.com/sharew ...
- JavaScript(变量、作用域和内存问题)
JavaScript是一个变量松散型的语言.(不像Java一样强类型语言.) JavaScript变量包括两种:基本类型(简单的数据段)和引用类型(对象). 一.基本数据类型(5种) Undefine ...
- 目标检测算法(2)SPP-net
本文是使用深度学习进行目标检测系列的第二篇,主要介绍SPP-net:Spatial Pyramid Pooling in Deep ConvolutionalNetworks for Visual R ...
- 64位 windows10,MYSQL8.0.13重置密码(忘记密码或者无法登录)
上一节的MySQL的配置安装里,并没有用到配置文件my.ini.那在MYSQL8.0.13如何解决密码重置问题呢.我去网上搜了好多的资料都是改配置文件my.ini的,后来终于找到了一条命令:操作步骤如 ...
- Javascript高级编程学习笔记(73)—— 表单(1)表单基础
表单 JS最初的一个用途就是帮助服务器分担处理表单的责任 时至今日,虽然web应用以及JS都有了长足的发展,但是表单依然是现在web应用中比较重要的部分. 因为默认的表单控件很丑,所以有时候我们会使用 ...
- 微信小程序合法域名配置-不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书
微信小程序合法域名配置-不校验合法域名.web-view(业务域名).TLS 版本以及 HTTPS 证书 很多教程说按照以上方式调用即可.但是当我们在程序中实际调用以上程序时,就会报错, http:/ ...
- AI - 框架(Frameworks)
1 - Scikit-Learn Sklearn(scikit-learn: machine learning in Python):https://scikit-learn.org/ 文档丰富而又详 ...
- 如何将云原生工作负载映射到 Kubernetes 中的控制器
作者:Janakiram MSV 译者:殷龙飞 原文地址:https://thenewstack.io/how-to-map-cloud-native-workloads-to-kubernetes- ...