我对以下代码有问题。可以看到我已经在C的构造函数中处理了A的构造函数抛出的异常,为什么还要在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;
}
你实际上不能catch构造函数中的异常。你可以处理它,但你必须重新抛出它或另一个异常。原因与对象完整性和对象生命周期有关:
如果建造a
抛出,一部分c
尚未初始化且完全缺失 - 生命周期a
永远不会开始。a
不是可选部分C
,否则它必须是一个指针或一个std::optional
(自 C++14 起 -boost::optional
在那之前)。
那么如何组装一个C
如果其重要部分之一无法建造怎么办?你不能。c
永远不能作为一个完整的对象存在,因此无法正常退出构造函数。这就是为什么如果成员对象的构造失败,整个对象的构造也必须失败的原因,即has to抛出异常。
如果你不抛出异常C::C
的 catch 块,编译器会为您执行此操作。
C++ 标准,§15.3,15:
如果控制到达构造函数或析构函数的函数 try 块的处理程序末尾,则重新抛出当前处理的异常。
有关该主题的更广泛的处理,请参阅http://www.gotw.ca/gotw/066.htm http://www.gotw.ca/gotw/066.htm
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)