在C++中从构造函数中抛出异常

use*_*215 8 c++ constructor exception-handling

我在这里阅读了几篇文章,否则可以从构造函数中抛出异常.但是,我注意到,如果从构造函数中抛出异常,它不会调用基类的析构函数或其数据成员.请考虑以下示例:

#include <iostream>
using namespace std;
struct C
{
    C() { cout << __FUNCTION__ << endl;  }
    ~C() { cout << __FUNCTION__ << endl; }
};

struct E: public C
{
    C c;
    E() { cout << __FUNCTION__ << endl; throw 4; }
    ~E() { cout << __FUNCTION__ << endl; }
};

int main()
{
    E e;
}


$ g++ test.cpp; ./a.exe
C
C
E
terminate called after throwing an instance of 'int'
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)

在这种情况下,E的构造函数抛出异常,但不会调用C的析构函数作为数据成员或基类.现在,如果C的析构函数执行一些清理操作,如关闭文件/套接字和删除堆分配,这可能会导致问题.

所以我的问题是为什么以及何时可以从构造函数中抛出异常.

Col*_*lin 12

如果您发现错误,将运行析构函数.当在C++中抛出未捕获的异常时,运行时调用std::terminate.默认情况下,std::terminate要求std::abort其特别不呼吁出路析构函数.

有了这个版本:

#include <iostream>
using namespace std;
struct C
{
    C() { cout << __FUNCTION__ << endl;  }
    ~C() { cout << __FUNCTION__ << endl; }
};

struct E: public C
{
    C c;
    E() { cout << __FUNCTION__ << endl; throw 4; }
    ~E() { cout << __FUNCTION__ << endl; }
};

int main()
{
    try {
        E e;
    } catch(...) {
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我得到输出:

C
C
E
~C
~C
Run Code Online (Sandbox Code Playgroud)