例外

异常提供了一种通过将控制转到称为特殊函数来在程序特殊情况下(如运行时错误)反应 处理

捕获异常,部分代码被置于异常检查。这是通过封闭的代码部分以完成 试块。当一个特殊情况是块内出现,抛出一个异常,控制到异常处理程序转移。如果没有抛出异常,代码继续正常进行,所有的处理程序被忽略。

一个例外是通过使用引发 throw关键字从内部 try块。异常处理程序声明为关键字 catch,必须立即后放置 try块:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// exceptions
#include <iostream>
using namespace std;

int main () {
  try
  {
    throw 20;
  }
  catch (int e)
  {
    cout << "An exception occurred. Exception Nr. " << e << '\n';
  }
  return 0;
}
出现异常。异常十五分。20


下异常处理代码被封闭在一个 try块中。在这个例子中的代码简单地抛出一个异常:

 
throw 20;
 


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

异常处理程序声明与 catch该的右括号后,立即关键字 try块。的语法 catch是类似于具有一个参数的常规功能。参数的类型是非常重要的,因为由传递的参数的类型 throw表达反对检查,只有在它们匹配的情况下,异常是由处理程序捕获。

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

如果一个省略号( ...)被用作参数 catch,该处理程序将捕获所有异常无论什么异常的类型抛出。这可以被用作捕获不受其他处理程序捕获所有异常的默认处理程序:

1
2
3
4
5
6
try {
  // code here
}
catch (int param) { cout << "int exception"; }
catch (char param) { cout << "char exception"; }
catch (...) { cout << "default exception"; }
 


在这种情况下,最后的处理程序将捕获抛出一个类型既不是的任何异常 int,也没有 char

经过一个异常被处理程序,执行后恢复 的try-catch块,而不是后 throw声明!

另外,也可以嵌套 try-catch多个外部内的块 try的块。在这些情况下,我们有一个内部的可能性 catch块转发例外它的外部的水平。这是用做表情 throw;不带参数。例如:

1
2
3
4
5
6
7
8
9
10
11
try {
  try {
      // code here
  }
  catch (int n) {
      throw;
  }
}
catch (...) {
  cout << "Exception occurred";
}
 


异常规范

旧的代码可能包含 动态的异常规格。他们现在不赞成使用C ++,但仍然支持。一个 动态的异常规格如下函数的声明,附加一个 throw说明它。例如:

 
double myfunction (char param) throw (int);
 


声明一个调用的函数 myfunction,这需要类型的一个参数 char和返回类型的值 double。如果这个函数抛出某种类型的比其他的异常 int,函数调用 的std ::意外 而不是寻找一个处理程序或调用  的std ::终止

如果此 throw指示符留空没有类型,这意味着 的std ::意外被称为是任何异常。没有功能 throw符(普通函数)永远不会调用 的std ::意外,但遵循的寻找自己的异常处理程序正常轨道。

1
2
int myfunction (int param) throw(); // all exceptions call unexpected
int myfunction (int param);         // normal exception handling 
 


标准异常

C ++标准库提供专为申报对象的基类来抛出例外。这就是所谓的 std::exception,并在被定义 <exception>标头。这个类有一个叫做虚成员函数 what返回一个空值终止的字符序列(类型的 char *),并可以在派生类中重写包含某种异常的描述。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 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;
}
我的例外发生。


我们已向通过引用捕获异常对象(注意,符号的处理程序 &的类型之后),因此这也可以捕获来自派生类 exception,像我们 myex类型的对象 myexception

所有异常由来源于此的C ++标准库抛出异常的组件抛出 exception类。这些是:

例外描述
bad_alloc通过抛出new的分配失败
bad_cast通过抛出dynamic_cast时,它在动态转换失败
bad_exception通过一定的动态异常抛出符
bad_typeid通过抛出 typeid
bad_function_call由空抛出function对象
bad_weak_ptr通过抛出shared_ptr当传递坏weak_ptr

另外从推导 exception,头 <exception>定义了可以通过自定义异常报告错误继承两个通用的异常类型:

例外描述
logic_error错误相关的程序的内部逻辑
runtime_error错误在运行时检测

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值