C++异常(一)

来源:互联网 发布:上海数据港怎么样 编辑:程序博客网 时间:2024/05/21 11:03

异常的关键字: try;  catch;  throw
  其中关键字try表示定义一个受到监控、受到保护的程序代码块;关键字catchtry遥相呼应,定义当try block(受监控的程序块)出现异常时,错误处理的程序模块,并且每个catch block都带一个参数(类似于函数定义时的数那样),这个参数的数据类型用于异常对象的数据类型进行匹配;而throw则是检测到一个异常错误发生后向外抛出一个异常事件,通知对应的catch程序块执行对应的错误处理。

例子如下:

int main()
{
cout << "In main." << endl;

//定义一个try block,它是用一对花括号{}所括起来的块作用域的代码块
try
{cout << "
try block , 准备抛出一个异常." << endl;

//这里抛出一个异常(其中异常对象的数据类型是int,值为1
//
try block中的代码是受到监控保护的,所以抛出异常后,程序的控制流便转到随后的catch block
throw 1;

cout << " try block , 由于前面抛出了一个异常,因此这里的代码是不会得以执行到的" << endl;
}
//
这里必须相对应地,至少定义一个catch block,同样它也是用花括号括起来的
catch( int& value )
{
cout << "
catch block , 处理异常错误。异常对象value的值为:"<< value << endl;
}

cout << "Back in main. Execution resumes here." << endl;
return 0;

}

 

一个try block可以有多个对应的catch block,每个catch block匹配一种类型的异常错误对象的处理,多个catch block呢就可以针对不同的异常错误类型分别处理。异常错误也是分级别的,有致命的、有一般的、有警告的,甚至还有的只是事件通知。例子如下:

int main()
{
try
{
cout << "
try block , 准备抛出一个int数据类型的异常." << endl;
throw 1;

cout << " try block , 准备抛出一个double数据类型的异常." << endl;
throw 0.5;
}
catch( int& value )
{
cout << "
catch block , int数据类型处理异常错误。”<< endl;
}
catch( double& d_value )
{
cout << "
catch block , double数据类型处理异常错误。”<< endl;
}

return 0;
}

 

一个函数中可以有多个trycatch结构块,例子如下:
int main()
{
try
{
cout << "
try block , 准备抛出一个int数据类型的异常." << endl;
throw 1;
}
catch( int& value )
{
cout << "
catch block , int数据类型处理异常错误。”<< endl;
}

//这里是二个trycatch结构块,当然也可以有第三、第四个,甚至更多
try
{
cout << "
try block , 准备抛出一个double数据类型的异常." << endl;
throw 0.5;
}
catch( double& d_value )
{
cout << "
catch block , double数据类型处理异常错误。”<< endl;
}

return 0;
}

 

一个try block可以有多个对应的catch block,这样便于不同的异常错误分类处理,其实这只是异常错误分类处理的方法之一(横向展开)。另外还有一种就是纵向的,也即是分层的、trycatch块是可以嵌套的,当在低层的trycatch结构块中不能匹配到相同类型的catch block时,它就会到上层的trycatch块中去寻找匹配到正确的catch block异常处理模块。例程如下:

int main()
{
try
{
//
这里是嵌套的trycatch结构块
try
{
cout << "
try block , 准备抛出一个int数据类型的异常." << endl;
throw 1;
}
catch( int& value )
{
cout << "
catch block , int数据类型处理异常错误。”<< endl;
}

cout << " try block , 准备抛出一个double数据类型的异常." << endl;
throw 0.5;
}
catch( double& d_value )
{
cout << "
catch block , double数据类型处理异常错误。”<< endl;
}

return 0;
}

 

trycatch块是可以嵌套分层的,并且通过异常对象的数据类型来进行匹配,以找到正确的catch block异常错误处理代码。通过异常对象的数据类型来进行匹配找到正确的catch block的过程。
  (1 首先在抛出异常的trycatch块中查找catch block,按顺序先是与第一个catch block块匹配,如果抛出的异常对象的数据类型与catch block中传入的异常对象的临时变量(就是catch语句后面参数)的数据类型完全相同,或是它的子类型对象,则匹配成功,进入到catch block中执行;否则到二步;
   2 如果有二个或更多的catch block,则继续查找匹配第二个、第三个,乃至最后一个catch block,如匹配成功,则进入到对应的catch block中执行;否则到三步;
   3 返回到上一级的trycatch块中,按规则继续查找对应的catch block。如果找到,进入到对应的catch block中执行;否则到四步;
   4 再到上上级的trycatch块中,如此不断递归,直到匹配到顶级的trycatch块中的最后一个catch block,如果找到,进入到对应的catch block中执行;否则程序将会执行terminate()退出。


  另外分层嵌套的trycatch块是可以跨越函数作用域的,例程如下:
void Func() throw()
{
//
这里实际上也是嵌套在里层的trycatch结构块
try
{
cout << "
try block , 准备抛出一个int数据类型的异常." << endl;
//
由于这个trycatch块中不能找到匹配的catch block,所以
//
它会继续查找到调用这个函数的上层函数的trycatch块。
throw 1;
}
catch( float& value )
{
cout << "
catch block , int数据类型处理异常错误。”<< endl;
}
}

int main()
{
try
{
Func();

cout << " try block , 准备抛出一个double数据类型的异常." << endl;
throw 0.5;
}
catch( double& d_value )
{
cout << "
catch block , double数据类型处理异常错误。”<< endl;
}
catch( int& value )
{
//
这个例子中,Func()函数中抛出的异常会在此被处理
cout << "
catch block , int数据类型处理异常错误。”<< endl;
}

return 0;
}

  嵌套的trycatch块是可以跨越函数作用域的,其实这里面还有另外一层涵义,就是抛出异常对象的函数中并不一定必须存在trycatch块,它可以是调用这个函数的上层函数中存在trycatch块,这样这个函数的代码也同样是受保护、受监控的代码;当然即便是上层调用函数不存在trycatch块,也只是不能找到处理这类异常对象错误处理的catch block而已,例程如下:
void Func() throw()
{
//
这里实际上也是嵌套在里层的trycatch结构块
//
由于这个函数中是没有trycatch块的,所以它会查找到调用这个函数的上层函数的trycatch块中。
throw 1;
}

int main()
{
try
{
//
调用函数,注意这个函数里面抛出一个异常对象
Func();

cout << " try block , 准备抛出一个double数据类型的异常." << endl;
throw 0.5;
}
catch( double& d_value )
{
cout << "
catch block , double数据类型处理异常错误。”<< endl;
}
catch( int& value )
{
//
这个例子中,Func()函数中抛出的异常会在此被处理
cout << "
catch block , int数据类型处理异常错误。”<< endl;
}

//如果这里调用这个函数,那么由于main()已经是调用栈的顶层函数,因此不能找
//
到对应的catch block,所以程序会执行terminate()退出。
Func();
// [
特别提示]:在C++标准中规定,可以在程序任何地方throw一个异常对象,
//
并不要求一定只能是在受到try block监控保护的作用域中才能抛出异常,但
//
如果在程序中出现了抛出的找不到对应catch block的异常对象时,C++
//
准中规定要求系统必须执行terminate()来终止程序。
//
因此这个例程是可以编译通过的,但运行时却会异常终止。这往往给软件
//
系统带来了不安全性。与此形成对比的是java中提供的异常处理模型却是不
//
永许出现这样的找不到对应catch block的异常对象,它在编译时就给出错误
//
提示,所以java中提供的异常处理模型往往比C++要更完善。

 return 0;
}

 
原创粉丝点击