1

有人可以解释一下以下代码中异常处理的顺序是如何发生的吗?它是如何评估的

“~B() 调用了 D() 中 D()Exception 的函数 try 块的处理程序”

#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(...) {}
}
4

3 回答 3

2

当您构造派生自另一个类的类的对象时,基类的构造函数在派生构造函数主体之前(显式或隐式)调用。D您在的构造函数主体中抛出异常。B此时已经建成。当异常传播出去时,B会调用 's 的析构函数来销毁部分构造的对象。

注意的第二个行为是重新抛出的异常。构造函数上的函数 try 块总是重新抛出异常。不可能忽略异常。如果是这样,您的对象将B已经被销毁。有关更深入的讨论,请参阅GotW #66 。

于 2013-06-12T17:42:11.943 回答
0

B get 在 D 的构造函数中为 Try 块创建。 throw 语句结束 try 块的执行,导致 B 被析构函数删除:

~B() called

这里实际上应该有一个换行符(你没有得到它还是你忽略了它?)。然后被抛出的对象 E 进入 catch 块并输出到屏幕:

Handler of function try block of D()Exception in D

那是你要找的吗?

于 2013-06-12T17:39:39.533 回答
0

当构造函数抛出未捕获的异常时,基类会自动销毁(因为它们是在进入构造函数主体之前成功构造的)。因此~B()在异常处理程序捕获异常之前被调用。

于 2013-06-12T17:42:08.600 回答