如何从函数中检索错误

How to retrieve error from function?

本文关键字:检索 错误 函数      更新时间:2023-10-16

假设我需要从配置中获取值。

哪个函数更正确?

int ret;
string value = config.getStringValue(string name, &ret);

string value;
int ret = config.getValue(string name, &value);

或者

string value = config.getStringValue(string name);
int ret = config.getResultCode();

结果代码的var名称更正确:ret, error等?

更新:对于@computerfreaker的评论:在相同的平台上没有例外,比如bada

您提出的两种解决方案都不是正确的c++方法。您提供的只是C。在c++中,使用异常

你的想法是:"我必须发送一些状态码给调用者"…这是C语言中通常处理错误的方式,但由于c++中存在异常,所以这样做更干净、更明智:

#include <exception>
std::string getValue() {
    if (...)
        throw std::exception("Unable to retrieve value.");
}

和调用者会做:

try {
    std::string val = getValue();
} catch (std::exception& e) { ... }

只要记住这个规则:按值抛出,按引用捕获


关于"异常是指处理异常状态" -这是真的。异常应该在发生意外/异常情况时使用。如果函数getValue依赖于值存在并且它可以被检索的事实,那么当您的代码由于某种原因无法检索该值时的情况是异常的,因此适合使用异常来处理它。

c++提供了几种从返回值的函数中报告错误的方法:

  1. 抛出异常当错误的原因与某些外部资源有关并且通常不会发生时,应该执行此操作。完美的例子:out of memory

  2. 返回特殊值表示失败,在呼叫现场遵循此约定。例如,返回""错误,并让调用者检查""

  3. 使用std::optional或类似的技术。这是第一个例子的高级版本。基本思想是返回一个特殊对象,该对象包含原始对象一个表示成功的布尔标志。使用特殊对象的规则是,只有当布尔标志表示成功时,才可以访问原始对象。我听过的这个习语的其他名字是"易出错的"answers"盒子"。这种解决方案和前一种解决方案在错误情况预期和频繁时是很好的备选方案——通常与用户输入完美匹配。

  4. Abort带有assert的程序。如果一个错误表明您自己的代码是错误的,这是一个很好的解决方案。在这种情况下,最好的办法通常是在程序产生危害之前尽快终止它。

  5. 使用全局错误状态并让调用者检查它。这是第三个例子。C代码喜欢用errno做很多这样的事情。然而,在c++中,这通常不被认为是一个好的解决方案。它不好的原因与任何类型的全局变量通常不好的原因相同。

  6. 不返回值本身,但使其成为out参数和引用。而是返回一个错误标志。这是第二个例子。它比之前的方法好,但仍然非常像c。我不建议这样做,因为它将强制调用者命名每个接收到的值。