注:博客中内容主要来自《狄泰软件学院》,博客仅当私人笔记使用。
测试环境:Ubuntu 10.10
GCC版本:9.2.0
一、C++异常处理
1)C++内置了异常处理的语法元素try...catch...
- try语句处理正常代码逻辑
- catch语句处理异常情况
- try语句中异常由对应的catch语句处理
try
{
double r = divide(1,0);
}
catch(...)
{
cout << "Divided by zero..." << endl;
}
2)C++throw语句抛出异常信息
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; //产生除0异常
}
return 0;
}
3)C++异常处理分析
- throw抛出的异常必须被catch处理
*当前函数能够处理异常,程序继续往下执行
*当前函数无法处理异常,则函数停止执行,并返回
未被处理的异常会顺着函数调用栈向上传播,直到被处理为止,否则程序将停止执行。
异常产生,function3不能处理;异常返回给function2,如果function2不能处理;异常返回,function1还不能处理异常,程序将异常停止执行。
编程实验
C++异常处理初探
64-1.cpp
#include <iostream>
#include <string>
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[])
{
double r = divide(1, 0);
cout << "r = " << r << endl;
return 0;
}
操作:
1) g++ 64-1.cpp -o 64-1.out编译正确,打印结果:
terminate called after throwing an instance of 'int'
Aborted(core dumped)
再抛出一个'int'型实例后控制台被调用
异常退出(信息转存)
分析:
如果抛出异常没有被处理,程序运行结束
2) 处理抛出的异常:
#include <iostream>
#include <string>
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;
}
cout << "run here" << endl;
return 0;
}
操作:
1)g++ 64-1.cpp -o 64-1.out编译正确,打印结果:
Divided by zero...
run here
分析:
double r = divide(1, 0);抛出异常后,这行代码后边内容cout << "r = " << r << endl;没有执行。
结论:如果抛出异常后,异常后边内容不会执行(异常安全角度来说,不是很好的处理方式),程序会直接去执行catch,异常处理后,程序会继续执行(例子中执行了run here)。
4)同一个try语句可以跟上多个catch语句
- catch语句可以定义具体处理的异常类型
- 不同类型的异常由不同的catch语句负责处理
- try语句中可以抛出任何类型的异常
- catch(...)用于处理所有类型的异常
- 任何异常都只能被捕获(catch)一次
5)异常处理的匹配规则
编程实验
异常类型匹配
64-2.cpp
#include <iostream>
#include <string>
using namespace std;
void Demo1()
{
try
{
throw 'c'; //抛出异常字符'c',对应catch(char c)
//throw 1; //抛出异常,对应catch(...),如果没有catch(...),程序异常
}
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(...) //3个点异常捕捉必须放在最后
{
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) g++ 64-2.cpp -o 64-2.out编译正确,打印结果:
catch(char c)
catch(string ss)
分析:
catch(...)能处理任何异常类型,一般放在最后边。
小结
1) C++中直接支持异常处理的概念
2) try...catch...是C++中异常处理的专用语句
3) try语句处理正常代码逻辑,catch语句处理异常情况
4) 同一个try语句可以跟上多个catch语句
5) 异常处理必须严格匹配,不进行任何的类型转换