这是一个广泛的问题,但我还是想问。希望我不会得到很多反对票:)
今天我参加了一次面试,(和往常一样)他们让我写一个计算一个数的阶乘的函数。之后,我们讨论了一些可能导致程序崩溃的原因,并讨论了如何让用户知道何时将负值传递给函数。
我个人说过使用断言或者返回一个特殊的数字让用户知道,但我不确定他是否对这些答案非常满意。
在您看来,什么是让用户知道传递给函数的非法值的好方法,或者在这种情况下最好的做法是什么?
这是一个广泛的问题,但我还是想问。希望我不会得到很多反对票:)
今天我参加了一次面试,(和往常一样)他们让我写一个计算一个数的阶乘的函数。之后,我们讨论了一些可能导致程序崩溃的原因,并讨论了如何让用户知道何时将负值传递给函数。
我个人说过使用断言或者返回一个特殊的数字让用户知道,但我不确定他是否对这些答案非常满意。
在您看来,什么是让用户知道传递给函数的非法值的好方法,或者在这种情况下最好的做法是什么?
C++ 的方式是抛出一个异常,如果出现问题,这将强制代码的用户显式执行某些操作 - 否则他/她的应用程序将终止。
这也是关于错误处理的广泛建议1 ,随着计算机能力的提高和编译器变得更聪明,关于使用异常对性能影响的争论已经开始淡出。
一些人声称使用异常会破坏代码的可读性,它会使其难以遵循和维护,这可能有些道理。
在更高级的情况下,抛出异常和清理远非一件容易的事,尽管在一个负责计算像一个数字的阶乘这样“简单”的东西的函数中——使用异常是一项相当容易的任务。
C++ 异常的最大问题(从我的角度来看)是缺少 -finally
子句,如果可以使用一个子句,那么在捕获异常后编写负责清理的代码将更简单任务。
推荐阅读:
脚注:
1.当然是主观意见。
如果您找到一种让代码调用者知道出现问题的好方法(可能是通过返回值、通过引用或异常设置的错误标志,或者几乎......任何东西),请确保您使用在整个项目中使用相同的错误通知系统。
没有什么比在错误处理方面使用不稳定的库更烦人的了。
我的第一选择是例外,因为它强制函数的用户处理该错误。如果您返回一个特殊值,用户可以忽略它并继续使用特殊的错误值,这将导致错误的结果。
验证您的输入总是一个好主意,这只是一个很好的编码实践。
让您的用户知道是一个有趣的问题,并且在很大程度上取决于您的实现。如果您正在构建一个基于 GUI 的程序,您总是可以在将输入插入到您的例程之前验证输入。如果输入无效,则您始终可以在屏幕上显示指示器。
如果您只是提供一个 API,那么我认为抛出异常可能是最好的方法。我已经看到函数 LIKE factorial 的实现,其中答案作为返回值提供,并且提供了一个单独的输入参数,例如用户提供的 unsigned int * 以便可以提供第二个返回值作为状态,其中返回的整数表示各种错误代码。
当我编写大部分自己的整个程序时,我非常喜欢在放置真正处理输入的例程之前预先验证来自接口的输入,并在输入无效时在 GUI 上提供输出!
我会抛出一个异常 - 更可能是一个检查异常(在 Java 中)。
请参阅:异常的优势 - 优势#2:在调用堆栈上传播错误与“如何让用户知道”的问题一致 - 用户开始调用,所以最终异常返回向上。
更具体地说,您需要使用 Checked Exception: A quick search for some info: Checked vs Unchecked Exception
已检查异常:表示程序无法立即控制的区域中的无效条件(无效的用户输入、数据库问题、网络中断、缺少文件)
与通常表示代码逻辑/实现失败的未检查异常相反
这取决于功能是什么,以及它是如何使用的。你可以有一个特殊的返回值,抛出一个异常,或者根据你的需要设置一个错误标志。我认为重要的是对此有一个合理的项目范围的哲学,并始终如一地使用它。
如果您想通知最终用户他对您的应用程序进行了不正确的输入,那么您应该显示一个对话框来说明这种情况。
但是,如果您正在谈论其他人实现您的代码,那么refp 的答案是最好的。