快速业务通道

C++中的异常(exception)

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-29
即可。即使在catch随后的block中,仍然可以继续throw。这时候有两种情 况,一是throw一个新类型的异常,这与普通的throw一样。二是要rethrow当前 这个异常,在这种情况下,throw不带参数即可表达。例如:

try{
  ...
}
catch(int){
  throw MyException ("hello exception"); // 抛出一个新的异常
}
catch(float){
  throw; // 重新抛出当前的浮 点数异常
}
2.4 函数声明

还有一个地方与throw关键字有关,就 是函数声明。例如:

void foo() throw (int); // 只能抛出int型 异常

void bar() throw (); // 不抛出任何异常

void baz(); // 可以抛出任意类型的异常或者不抛出异常

如果一个函数的声明中带有throw限定符,则在函数体中也必须同样出现:

void foo() throw (int)
{
  ...
}

这里有一个问题,非常隐蔽,就是即使你象上面一样编写了foo()函数,指定它 只能抛出int异常,而实际上它还是可能抛出其他类型的异常而不被编译器发现 :

void foo() throw (int)
{
  throw float; // 错误!异常类型错误!会被编译器指出
  ...
  baz(); // 正确!baz()可能抛出非int异常而编译器又不能发现!
}
void baz()
{
  throw float;
}

这种情况的直 接后果就是如果baz()抛出了异常,而调用foo()的代码又严格遵守foo()的声明 来编写,那么程序将abort()。这曾经让我很恼火,认为这种机制形同虚设,但 是还是有些解决的办法,请参照“使用技巧”中相关的问题。

3. 异常使用技巧

3.1 异常是如何工作的

为了可以有把握的使 用异常,我们先来看看异常处理是如何工作的。

3.1.1 unwinding stack

我们知道,每次函数调用发生的时候,都会执行保护现场寄存器、参数压栈、为 被调用的函数创建堆栈这几个对堆栈的操作,它们都使堆栈增长。每次函数返回 则是恢复现场,使堆栈减小。我们把函数返回过程中恢复现场的过程称为 unwinding stack。

异常处理中的throw语句产生的效果与函数返回相同 ,它也引发unwinding stack。如果catch不是在throw的直接上层函数中,那么 这个unwinding的过程会一直持续,直到找到合适的catch。如果没有合适的 catch,则最后std::unexpected()函数被调用,说明发现了一个没想到的异常, 这个函数会调用std::terminate(),这个terminate()调用abort(),程序终止 (core dump)。

在“简介”中提到的longjmp()也同样会 unwinding stack,但是这是一个C函数,它就象free()不会调用对象的析构函数 一样,它也不知道在unwinding stack的过程中调用栈上对象的析构函数。这是 它与异常的主要区别。

3.1.2 RTTI

在unwinding stack的过程中,程序会 一直试图找到一个“合适”的catch来处理这个异常。前面我们提到 throw和catch的关系很象是函数调用和函数原型的关系,多个catch就好象一个 函数被重载为可以接受不同的类型。根据这样的猜测,好象找到合适的catch来 处理异常与函数重载的过程中找到合适的函数原型是一样的,没有什么大不了的 。但实际情况却很困难,因为重载的调用在编译时刻就可以确定,而异常的抛出 却不能,考虑下面的代码:

void foo() throw (int)
{
  throw int;
}
void bar()
{
  try{
     foo();
  }
  catch(int){
    ...
  }
  catch(float){
    ...
  }
}
void baz()
{
  try{
    foo();
  }
   catch(int){
    ...
  }
  catch(float){
     ...
  }
}

foo()在两个地方被调用,这两次异常 被不同的catch捕获,所以在为throw产生代码的时候,无法明确的指出要由哪个 catch捕获,也就是说,无法在编译时刻确定。

仍然考虑这个例子,让我 们来看看既然不能在编译时刻确定throw的

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号