【发布时间】:2011-01-12 21:07:00
【问题描述】:
我已经搜索过这个问题的答案,但还没有找到。
当一个对象在构造函数的末尾抛出异常时,该对象是有效的还是其中之一“取决于构造技术”?
例子:
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");
}
}
程序:
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;
}
在这个例子中,知道f1是一个近似值,捕获到异常后是否可以使用f1?
数据成员已被构造和初始化。
我没有看到任何违反上述规定的 C++ 语言规则。
编辑:将错误增量值从 5.0E05 更改为 5.0E-5。
【问题讨论】:
-
你真的可以访问 f1 的作用域吗?
-
那么接下来的挑战就是如何在对象构造失败之后使用它。也许这对于 SO wiki 来说是一个很好的主题。
-
绝对不可能。 当抛出异常时,它会向外传播。这意味着它离开当前范围,检查是否可以被捕获,如果不能,则重复。当构造函数抛出异常时,very 离开的第一个作用域是每次都在其中创建对象的作用域。要么是因为它直接在 try/catch 块中,要么是因为它需要离开作用域来寻找一个。
标签: c++ exception-handling constructor exception