【问题标题】:C++ constructor initializer list throw exceptionsC++ 构造函数初始化列表抛出异常
【发布时间】:2013-07-07 23:49:57
【问题描述】:

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

【问题讨论】:

  • 异常是否真的从C 的构造函数中传播出去?如果没有,为什么还要抓住它?
  • 谁建议你也捕获main() 中的异常?问他这个问题!
  • @chris:是的,从统计上讲,我是对的。 ;-)
  • 对于它的价值,像构造函数-try-blocks这样的异国语言功能在聚会上可以起到很好的破冰作用。
  • @Nawaz 是的,那些棘手的语言角落之一偶尔会遇到 - 但在阅读了 Sutter 的解释之后,其他任何事情都没有意义;-)

标签: c++ list exception constructor initializer


【解决方案1】:

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

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

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

如果您没有在 C::C 的 catch 块中抛出异常,编译器会为您这样做。

C++ 标准,§15.3,15:

如果控制到达构造函数或析构函数的函数try块的处理程序的末尾,则重新抛出当前处理的异常。

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

【讨论】:

  • 谢谢大家,尤其是@Arne Mertz。 C++ 标准解释了一切,:-)
猜你喜欢
  • 1970-01-01
  • 2011-02-09
  • 1970-01-01
  • 2022-01-19
  • 2010-10-16
  • 2014-11-03
  • 2010-09-14
  • 2020-10-17
相关资源
最近更新 更多