【问题标题】:C++ Exceptional handling queryC++异常处理查询
【发布时间】:2013-06-12 17:28:43
【问题描述】:

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

“~B()调用D()异常的D()函数块的Handler”

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

【问题讨论】:

  • 解释一下呢?

标签: c++ exception-handling constructor


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    ~B() called
    

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

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

    这就是你要找的吗?

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-29
        • 1970-01-01
        • 2013-05-27
        • 1970-01-01
        • 2012-06-11
        • 2011-04-27
        相关资源
        最近更新 更多