有人可以解释一下如何在下面的代码中进行异常处理的顺序吗?它是如何评价
的“~B()调用函数的Handler尝试D()中的异常D”
#include "stdafx.h"
#include <iostream>
using namespace std;
class E {
public:
const char* error;
E(const char* arg): error(arg) {}
};
class B {
public:
B() {};
~B(){cout<<"~B() called"<<endl;}
};
class D: public B {
public:
D();
~D() { cout<<"~D() called"<<endl; }
};
D::D() try :B(){
throw E("Exception in D");
} catch(E&e)
{
cout<<"Handler of function try block of D()"<<e.error<<endl;
};
int main()
{
try {
D val;
}catch(...) {}
}
答案 0 :(得分:2)
当您构造从另一个类派生的类的对象时,在派生的构造函数体之前调用(显式或隐式)基类的构造函数。你在D
的构造函数体中抛出一个异常。此时已经构建了B
。当异常传播出去时,调用B
的析构函数来销毁部分构造的对象。
注意的第二个行为是重新抛出的异常。构造函数上的函数try块总是重新抛出异常。无法忽略异常。如果是的话,你的对象将被B
遗留下来。有关更深入的讨论,请参阅GotW #66。
答案 1 :(得分:0)
在D的构造函数中为Try块创建了B get.stall语句结束了try块的执行,导致B被析构函数删除:
~B() called
这里实际上应该有一个换行符(你没有得到它还是没有省略它?)。然后抛出的对象E进入catch块,在那里输出到屏幕:
Handler of function try block of D()Exception in D
这就是你要找的东西吗?
答案 2 :(得分:0)
当构造函数抛出未捕获的异常时,基类会自动被破坏(因为它们是在输入构造函数体之前成功构造的)。因此,在异常处理程序捕获异常之前调用~B()
。