c++教程(二十三: Exceptions)

来源:互联网 发布:淘宝客服沟通技巧 编辑:程序博客网 时间:2024/06/06 07:49

Exceptions(异常)

Exceptions 异常提供了一种方法来对程序中的异常情况(如运行时错误)进行响应,将控制传递给称为handlers处理器的特殊函数。

若要捕获异常,则在异常检查下放置一部分代码。这是通过在 try-block中封装代码部分来实现的。当异常情况出现在该块中时,会抛出异常,将控制转移到异常处理程序。如果没有抛出异常,则代码将继续正常,所有处理程序将被忽略。

通过从try 块内部使用抛出关键字引发异常。使用关键字catch声明异常处理程序,必须在try 块之后立即放置:

// exceptions#include <iostream>using namespace std;int main () {  try  {    throw 20;  }  catch (int e)  {    cout << "An exception occurred. Exception Nr. " << e << '\n';  }  return 0;}结果为An exception occurred. Exception Nr. 20

异常处理下的代码包含在一个try块中。在这个例子中,这个代码只抛出一个异常:

throw 20;

throw 表达式接受一个参数(在这种情况下,整型值20),它作为参数传递给异常处理程序。

异常处理程序在try块的结束括号之后立即用catch关键字声明。catch的语法类似于带有一个参数的正则函数。此参数的类型是非常重要的,因为对throw 表达式传递的参数类型进行了检查,只有在它们匹配的情况下,异常才会被该处理程序捕获。

多个处理程序(即,多catch表达式)可以被链接;每一个具有不同的参数类型。只执行参数类型与抛出语句中指定的异常类型相匹配的处理程序。

try {  // code here}catch (int param) { cout << "int exception"; }catch (char param) { cout << "char exception"; }catch (...) { cout << "default exception"; }

在这种情况下,最后的处理程序会抛出的任何异常的类型既不是int也不是 char。
处理程序异常后,执行将在尝试catch块后恢复,而不是在抛出语句之后!。

也可以在更多外部try块中嵌套try-catch块。在这些情况下,我们有一个内部catch块将异常转发到外部级别的可能性。这是用表达式抛出,没有参数。例如:

try {  try {      // code here  }  catch (int n) {      throw;  }}catch (...) {  cout << "Exception occurred";}

Exception specification

旧代码可能包含动态异常规范。他们现在在C++不提倡的,但还是支持。一个动态的异常说明如下一个函数声明,添加一个throw 说明符。例如:

double myfunction (char param) throw (int);

这里声明一个函数MyFunction,它带有一个char类型参数和返回一个double类型的值。如果函数抛出一些类型不是int,函数调用 std::unexpected 而不是寻找一个处理程序或调用std::terminate

如果throw说明符是空的类型,这意味着std::unexpected 是被其他外部调用。没有throw说明符函数(的正常功能)不调用std::unexpected ,但按照正常的路径寻找自己的异常处理程序。

int myfunction (int param) throw(); // all exceptions call unexpectedint myfunction (int param);         // normal exception handling

标准异常(Standard exceptions)

C++标准库提供了一个基类用于对象被抛出的异常。它被称为std::exception,并在头文件中定义。这个类有一个虚成员函数叫what ,返回一个空终止字符序列(类型为char *),可以覆盖在派生类中含有某种异常的描述。

// using standard exceptions#include <iostream>#include <exception>using namespace std;class myexception: public exception{  virtual const char* what() const throw()  {    return "My exception happened";  }} myex;int main () {  try  {    throw myex;  }  catch (exception& e)  {    cout << e.what() << '\n';  }  return 0;}

我们放了一个捕获异常对象的引用(在类型符通知)处理程序,因此这个catch也是exception的派生类,比如myex对象是myexception对象类型。

通过对C++标准库异常类抛出异常来自这部分抛出的异常。这些是:
这里写图片描述
也从exception派生,头文件定义了两个泛型异常类型,这些异常类型可以由自定义异常继承来报告错误:
这里写图片描述

需要检查的标准异常的一个典型例子是内存分配:

// bad_alloc standard exception#include <iostream>#include <exception>using namespace std;int main () {  try  {    int* myarray= new int[1000];  }  catch (exception& e)  {    cout << "Standard exception: " << e.what() << endl;  }  return 0;}

通过本例中的异常处理程序捕获是一个bad_alloc。因为bad_alloc来自标准库类exception,它能被捕捉到(捕捉参考,捕捉所有相关的类)。

0 0
原创粉丝点击