C++忽略构造函数异常的分支

Tho*_*ews 5 c++ constructor exception-handling exception

我搜索了SO的答案,但没有找到答案.

当一个对象在构造函数的末尾抛出一个异常时,该对象是有效的还是这个'取决于构造技术'?

例:

    struct Fraction
    {
      int m_numerator;
      int m_denominator;
      Fraction (double value,
                int denominator);
    };
    Fraction::Fraction(double value, int denominator)
    :  m_numerator(0), m_denominator(denominator)
    {
      if (denominator == 0)
      {
/* E1 */        throw std::logic_error("Denominator is zero.");
      }
      m_numerator = static_cast<int>(value * static_cast<double>(denominator));
      double actual_value = 0.0;
      actual_value = static_cast<double>(m_numerator) / static_cast<double>(m_denominator);
      double error = fabs(actual_value - value);
      if (error > 5.0E-5)
      {
/* E2 */  throw std::logic_error("Can't represent value in exact fraction with given denominator");
      }
    }
Run Code Online (Sandbox Code Playgroud)

该程序:

int main(void)
{
    try
    {
        Fraction f1(3.14159264, 4); // Throws exception, E2 above.
    }
    catch (...)
    {
        cerr << "Fraction f1 not exactly representable as fraction with denom. of 4.\n";
    }

    // At this point, can I still use f1, knowing that it is an approximate fraction?

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

在这个例子中,可以在捕获异常后使用f1,知道它是一个近似值吗?

数据成员已经构建和初始化.

我没有看到任何违反上述规则的C++语言规则.

编辑:将错误增量值从5.0E05更改为5.0E-5.

Jon*_*vis 5

捕获到异常后,f1超出范围.它不再存在,因此您无法使用它.


fbr*_*eto 4

乔纳森的回答是正确的。此外,虽然分数可能处于有效状态,但我不建议使用异常进行流量控制,尤其有关对象状态的通信。相反,请考虑向您的 Fraction 对象 API 添加某种is_exactly_representable返回bool.