2013-11-24 99 views
2

大家好我遇到一些困难,理解下面的代码处理未捕获的异常,我有几个关于下面的例子的问题。C++处理未捕获的异常

1)只是想知道为什么输出是:“打电话给我的意外”和“抓坏表情”,而不是“打电话给我的意外”,“夹缝X”

2)什么throw(X,Y, bad_exception)意味着“ void f()'函数。

3)是什么typedef void (*pfv)();实际上意味着

class X { }; 
class Y { }; 
class A { }; 

typedef void (*pfv)(); 

void my_terminate() { 
    cout << "Call to my_terminate" << endl; 
    abort(); 
} 

void my_unexpected() { 
    cout << "Call to my_unexpected" << endl; 
    throw; 
} 

void f() throw(X,Y, bad_exception) { 
    throw A(); 
} 

void g() throw(X,Y) { 
    throw A(); 
} 
int main() 
{ 
    pfv old_term = set_terminate(my_terminate); 
    pfv old_unex = set_unexpected(my_unexpected); 
    try { 
    cout << "In first try block" << endl; 
    f(); 
    } 
    catch(X) { 
    cout << "Caught X" << endl; 
    } 
    catch(Y) { 
    cout << "Caught Y" << endl; 
    } 
    catch (bad_exception& e1) { 
    cout << "Caught bad_exception" << endl; 
    } 
    catch (...) { 
    cout << "Caught some exception" << endl; 
    } 
} 

遗憾的多个问题被问,希望有人能够在通俗地说向我解释。感谢和欣赏..

+1

不!不要使用投掷规格。这通常被认为不适用于设置API。 –

+0

@ g-makulik我不知道使用throw spec是不明智的,但我对C++超级新手,所以只是想知道为什么他们会是以下输出。 – user2975932

+0

看看斯图尔特的答案。这很清楚,为什么使用throw规格(除了'nothrow'之外)使得提供良好的类接口不必要地复杂化。除了保证**'不要抛出任何异常'之外,任何事情都会使维护变得更加复杂,以至于一直处于不可预知的陷阱之中。 –

回答

2

1)当您拨打f时,它会抛出一个异常,其类型(A)不是其异常规范的一部分。这导致注册的意外处理程序被调用,在这种情况下是my_unexpected。这会打印“调用my_unexpected”,然后重新抛出原始异常(如前所述,该异常的类型不属于f的异常规范的一部分),这会导致bad_exception(但仅因为bad_exception是异常规范的一部分的f)。然后在main中捕获,并打印“Caught bad_exception”。

2),意思是“f可能抛出X,一个Ybad_exception,如果它试图扔任何东西那么意外处理程序将被称为”。 3)它意味着“pfv是指向不带参数和void返回类型的函数的指针的类型”。因此pfv old_term;意味着old_term就是这样一个函数指针。


这是一个有益的联系,对于它的价值:

http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr162.htm

的特别相关位是底部,在那里它说(重点煤矿):

如果意外的()没有抛出(或重新抛出)f()的异常规范所允许的对象,那么C++运行时会执行以下两个操作之一:

  • 如果f的异常规范()包括在类的std :: bad_exception,意外()将抛出 类型的std :: bad_exception的目的,以及C++运行时间将在另一个 处理器搜索f()的调用。
  • 如果f()的异常规范没有包含类std :: bad_exception,则调用函数terminate()。