假设我需要从配置中获取值。
哪种功能更正确?
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
等相同平台上没有例外答案 0 :(得分:3)
您提出的解决方案都不是正确的C ++方式。你提供的只是C.在C ++中,使用异常
答案 1 :(得分:2)
您的想法是:“我必须向调用者发送一些状态代码” ...这是您通常在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
依赖于值存在且可以检索的事实,那么当您的代码由于某种原因无法检索此值时的情况是例外的,因此适合使用异常处理它。
答案 2 :(得分:1)
C ++提供了几种报告函数的方法,这些函数返回一个值:
抛出例外。当错误的原因是某些外部资源并且通常不会发生时,应该这样做。完美的例子:内存不足。
返回特殊值以指示失败,并在呼叫站点遵循此约定。例如,返回""
表示错误,并让来电者检查""
。
使用std::optional
或类似技巧。这是你的第一个例子的高级版本。基本思想是返回一个特殊对象,其中包含原始对象 和一个表示成功的布尔标志。特殊对象与规则一起使用,即如果布尔标志指示成功,则只能访问原始对象。我听过的这个成语的其他名称是“Fallible”和“Box”。当出现错误情况并经常出现错误情况时,此解决方案和前一个解决方案是很好的选择 - 通常是用户输入的完美匹配。
使用assert
中止该程序。如果错误表明您自己的代码错误,这是一个很好的解决方案。在这种情况下,最好的办法通常是在程序造成任何伤害之前尽快终止程序。
使用全局错误状态并让调用者进行检查。那是你的第三个例子。 C代码很想用errno
做很多事情。但是,在C ++中,这通常不被认为是一个好的解决方案。由于任何类型的全局变量通常都是错误的原因相同,这是不好的。
不要返回值本身,而是使用引用将其设为 out参数。返回错误标志。这是你的第二个例子。它比以前的方法更好但仍然非常像C。我不建议这样做,因为它会强制来电者为每个收到的值命名。