gpt4 book ai didi

C++构造函数初始化列表抛出异常

转载 作者:可可西里 更新时间:2023-11-01 18:16:08 26 4
gpt4 key购买 nike

我对以下代码有疑问。可见我已经在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;
}

最佳答案

您实际上无法捕获构造函数中的异常。你可以处理它,但你必须重新抛出它或另一个异常。原因是关于对象完整性和对象生命周期:

如果 a 的构造抛出,则 c 的一部分尚未初始化并且完全丢失 - a 的生命周期永远不会开始。 a 不是 C 的可选部分,否则它必须是指针或 std::optional(自 C++14 - boost::optional 之前。

那么,如果无法构建一个 C 的重要部分,您如何组装它呢?你不能。 c 永远不可能作为一个完整的对象开始存在,因此您无法正常退出构造函数。这就是为什么如果一个成员对象的构造失败,整个对象的构造必须失败,即必须抛出异常。

如果您不在 C::C 的 catch block 中抛出异常,编译器会为您抛出异常。

C++ 标准,§15.3,15:

The currently handled exception is rethrown if control reaches the end of a handler of the function-try-block of a constructor or destructor.

有关该主题的更广泛的处理,请参阅 http://www.gotw.ca/gotw/066.htm

关于C++构造函数初始化列表抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17564037/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com