#include <iostream> using namespace std; double Div(double a, double b) { return a/b; } //除数为0的时候 发生异常 main() { cout<<Div(1,0)<<endl; return 0; }
1:c++异常处理机制
C++异常处理机制是一个用来有效地处理运行错误的非常强大且灵活的工具,它提供了更多的弹性、安全性和稳固性,克服了传统方法所带来的问题.
异常的抛出和处理主要使用了以下三个关键字: try、 throw 、 catch 。
抛出异常即检测是否产生异常,在C++中,其采用throw语句来实现,如果检测到产生异常,则抛出异常。该语句的格式为:
throw 表达式;
如果在try语句块的程序段中(包括在其中调用的函数)发现了异常,且抛弃了该异常,则这个异常就可以被try语句块后的某个catch语句所捕获并处
理,捕获和处理的条件是被抛弃的异常的类型与catch语句的异常类型相匹配。由于C++使用数据类型来区分不同的异常,因此在判断异常时,throw语
句中的表达式的值就没有实际意义,而表达式的类型就特别重要
hrow语句用于将异常“ 对象 ”” 抛出
throw语句将异常抛出, 如果在当前函数中没有 try… catch 语句能够处理该异常, 则当前函数将立即返回
异常被传递到上层调用函数, 仍然需要try …catch语句进行处理, 如果上层函数也没有能力处理该异常 ,则异常继续向更上层函数的函数传递。。。
如果在函数调用栈中的所有函数都无法处理抛出的异常, 则程序异常中止
一个try语句块可以跟上多个catch语句块
同一个try语句块可以抛出多种不同类型的异常
不同类型的异常由不同的catch语句块负责处理
异常被抛出后会自上而下逐一匹配catch语句块
异常匹配时, ,不会进行默认类型转换
异常处理是程序中随处可见的情况
在工程实践中, 大多数的代码都是用于处理异常的质量直接决定最终产品的质量
C++提供了 try… catch语句用于将正常逻辑代码与异常语句处理代码进行分开处理
catch(… ) 可以捕获所有异常但却无法得到异常信息
catch(… )一般作为最后一个异常处理块出现
在 catch(…)语句块中 ,可以通过不带参数的throw语句抛出捕获的异常
try { for(int i = 0; i < 10; i++) { try { cout<<test(i)<<endl; } catch(...) { cout<<"Exception Occur"<<endl; throw;//在 catch(…)语句块中 ,可以通过不带参数的throw语句抛出捕获的异常 } } } catch(int e) { cout<<"Catch()..."<<e<<endl; }
不要在构造函数中抛出异常
在构造函数可能申请系统资源, 而在构造函数中抛出异常会导致对象构造不完全
不完全对象的析构函数是不会被调用的,可 因此可能造成资源泄漏
#include <iostream> using namespace std; class Test { int* p; public: Test() { cout<<"Test()"<<endl; p = new int[5]; throw 1; } ~Test() { cout<<"~Test()"<<endl; delete[] p; } }; int main() { try { Test t; } catch(int e) { cout<<"Catch:"<<e<<endl; } return 0; } /* Test() Catch:1 由输出结果可以看到,没有调用析构函数,会造成内存泄露 */
2:异常的接口声明:
为了加强程序的可读性,使函数的用户能够方便地知道所使用的函数会抛出哪些异常,可以在函数的声明中列出这个函数可能抛出的所有异常类型,例如:
void fun() throw( A,B,C,D);
这表明函数fun()可能并且只可能抛出类型(A,B,C,D)及其子类型的异常。
如果在函数的声明中没有包括异常的接口声明,则此函数可以抛出任何类型的异常,例如:
void fun();
一个不会抛出任何类型异常的函数可以进行如下形式的声明:
void fun() thow();
3:工程中的异常应用:
在工程中会定义一系列的异常类
通过继承,可以得到一个异常类族
每个类代表工程当中可能出现的一种异常类型
由于对象构造与拷贝的开销,在定义catch语句块时使用引用作为参数。
在工程中可以使用标准库中的异常类
可将标准库中的异常类作为基类派生新的异常类
标准库中的异常都是从exception类派生的
exception类有两个主要的分支
logic_error用于描述程序中出现的逻辑错误
如 :传递无效参数
runtime_error用于描述无法预料的事件所造成的错误
如 : 内存耗尽,
ogic_error和runtime_error都提供了一个参数为字符串的构造函数, ,这样就可以保持错误信息
通过what()成员函数就可以得到错误的信息
4:函数级别try语法 秀操作:
第一种:
int func(int i)
{
try
{return i;}
catch(...)
{return -1;}
}
第二种:(秀代码)
int func(int i) try
{
return i;
}
catch(...)
{return -1;}
5:总结:
<1>catch(… )可以捕获所有异常 可以捕获所有异常
<6>如果抛出的异常一直没有函数捕获(catch),则会一直上传到c++运行系统那里,导致整个程序的终止。