1

我正在编写一个 C++ 类,它将一些双精度值存储在一个向量(称为 mpValues)中并计算它们的平均值。构造时,值数组为空,因此执行此计算将返回 0.0/0.0。

我决定要求零值的平均值是一个错误。因此,最好返回 NaN 并显示错误消息,以便用户意识到该问题。代码如下所示:

double Average::CalculateAverage() const
{
    if(mpValues->size() == 0){
        std::cerr << "Instance of Average at: " << this << " contains no values.\n"
                  << "In this case the arithmetic mean is defined as NaN." <<std::endl;

        return 0.0/0.0;
    }
    else{
        ...calculate the arithmetic mean
    }
}

这是一种明智的方法,还是您有更好的建议?通常,我不会那么挑剔,但这是对工作机会的考验,所以我想避免做出错误的决定。

提前致谢!

4

5 回答 5

7

标准选项是返回 NaN、抛出异常或返回选项,例如 boost::optional。每个都有优点和缺点,已经被无数人详细审查过。只是不要在函数中显示错误消息,因为这违反了单一责任原则

于 2012-10-03T08:23:07.223 回答
3

你已经回答了这个问题:

我决定要求零值的平均值是一个错误。

因此,无需返回 NaN 或处理零除法。您可以创建自己的异常类(例如 EmptyVectorError)并抛出并捕获它。

于 2012-10-03T08:20:31.110 回答
1

这是一个 C++ 问题,所以我们应该给出一个 C++ 答案。根据单一职责原则(Don Reba 提到),我们得出结论,从您的函数内部报告错误是不合适的。有两个主要选项。

1明确指定average(container)用空容器调用你是未定义的行为(UB)。这是 C++std库中许多算法的标准做法。它允许您忽略空容器的可能性并直接返回sum/size()。您可以assert(size()>0);在调试模式下添加(或类似的)。

2明确允许 API 中的空容器(我认为这是您想要的)。在这种情况下,退货sum/size()是不合适的。它可能会返回NaN或触发一个信号,具体取决于错误设置,但即使是 aNaN也不容易捕获(我认为isnan()它不是标准库函数)。所以你必须以一种干净的方式返回未定义的结果。这可以通过抛出一个适当的异常或返回一个类型来完成,例如boost::optional<>(usta 建议的),它明确允许一个不是错误的未定义值(与 不同NaNdouble

我认为抛出异常是 C++ 中最合适的方式(如果您选择选项 2)。

于 2012-10-03T09:09:41.837 回答
0

boost::optional<double>我建议将返回类型更改为。

链接到文档

于 2012-10-03T08:18:04.820 回答
-1

您有 2 个选项 - 返回 NaN 或抛出异常。你应该做什么,取决于使用情况。

1)客户端只显示平均值:那么我会选择简单地返回 NaN。这样,客户就不会被迫为他不关心的事情编写错误处理代码。

2)客户端使用平均值计算新值:那么这很困难。通过抛出一个异常,你强迫他明确地处理它。这可能是件好事。另一方面 - 据我所知,双值 NaN 可用于计算。这也取决于您的其他工作。如果你总是使用异常,你也应该使用一个。如果你总是使用错误代码,你应该使用 NaN。如果你混合 - 你应该清理它。

PS:我不会写 0.0/0.0 而是使用std::numeric_limits。它更容易阅读。

于 2012-10-03T08:30:07.580 回答