Jav*_*eta 7 c++ constructor exception list initializer
我有以下代码的问题.正如我们所看到的,我已经处理了A的构造函数在C的构造函数中抛出的异常,为什么我还要在main函数中再次捕获并处理异常呢?
#include <iostream>
class WException : public std::exception
{
public:
WException( const char* info ) : std::exception(info){}
};
class A
{
public:
A( int a ) : a(a)
{
std::cout << "A's constructor run." << std::endl;
throw WException("A constructor throw exception.");
}
private:
int a;
};
class B
{
public:
B( int b ) : b(b)
{
std::cout << "B's constructor body run." << std::endl;
throw WException("B constructor throw exception");
}
private:
int b;
};
class C : public A, public B
{
public:
C( int a, int b ) try : A(a), B(b)
{
std::cout << "C's constructor run." << std::endl;
}
catch( const WException& e )
{
std::cerr << "In C's constructor" << e.what() << std::endl;
}
};
int main( int argc, char* argv[] )
{
try
{
C c( 10, 100 );
}
catch( const WException& e )
{
std::cerr << "In the main: " << e.what() << std::endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Arn*_*rtz 16
您实际上无法在构造函数中捕获异常.你可以处理它,但你必须重新抛出它或另一个例外.原因是对象完整性和对象生命周期:
如果建造a投掷,一部分c尚未初始化并完全缺失 - a从未开始的生命.a不是一个可选的部分C,否则它必须是指针或std::optional(因为C++ 14 - boost::optional之前).
那么,C如果无法构建其中一个重要部件,您如何组装?你不能.c永远不能作为一个完整的对象开始存在,所以你无法正常退出构造函数.这就是为什么如果构件对象的构造失败,整个对象的构造必须失败,即必须抛出异常.
如果你没有在C::Ccatch块中抛出异常,编译器会为你执行此操作.
C++标准,§15.3,15:
如果控制到达构造函数或析构函数的function-try-block的处理程序的末尾,则重新抛出当前处理的异常.
有关该主题的更广泛的处理,请访问http://www.gotw.ca/gotw/066.htm