c++ - 在 C++ 中抛出异常的替代方法是什么
问题描述
我最近面试了一家公司实习。他们让我写一个递归函数来计算给定整数的阶乘。所以我在纸上写了这样的东西:
int factorial(int n){
if(n<0){throw std::invalid_argument( "received negative value" );}
if(n == 0){return 1;}
else{
return n * factorial(n-1);
}
}
然后作为后续行动,他们问了我类似的问题
“抛出异常对这个函数的用户有什么责任?”
“你能用其他方式处理这件事吗?”
“你能优雅地处理它吗?”
我真的不知道他们在寻找/暗示什么。谁能告诉我我是否在这里遗漏了什么?
解决方案
检查异常的要求要求调用者捕获和处理异常,使他们的代码变得混乱,并且还增加了处理异常的处理开销。
还有其他一些方法可以返回而不引发异常。
- 一个数的阶乘不能为零或负数,因此可以返回 0 或负整数(即“幻数”)来表示该阶乘不存在或找不到。类似地,如果输入太大而无法计算 a 范围内的阶乘
int
,您也可以返回这个无效值,或者将特定值设置为指示故障模式的值(例如 0 表示输入负数,-1 表示输入太大,-2 表示任何其他异常)。 - 您可以更改方法签名以返回指向 a 的指针,
int
并将逻辑设置为返回NULL
以指示无结果(C 代码经典地填充了“调用后检查 null 以确保成功”逻辑)。如果找到阶乘,则返回一个指向int
持有该值的指针,该值是使用在堆上创建的new
。 - 您可以接受 a
short int
作为输入参数,从而消除许多(但不是全部)阶乘太大而无法适应返回值的输入值。这不会完全解决问题,但每一点都有帮助。结合另一种方法,您可以进一步减少潜在的故障模式。
上面的第一个选项可以很优雅,因为它允许调用者以多种方式使用该值(例如,打印它,在进一步的数学运算中使用它)而无需输入非数字或无法处理的数字和。缺点是你可能会得到一个毫无意义的数字。在某些情况下,输出“建筑物中的楼层数:-1,成本:$-1”比在重要的演示中崩溃要好!类似的情况(在业务规则方面无效但可以处理数据,在这种情况下是指针)在超级马里奥兄弟中产生了著名的负世界错误!
最后一个值更加优雅,因为它有助于防止无效数据甚至到达函数。正如他们所说,垃圾进,垃圾出。
推荐阅读
- javascript - 删除事件侦听器未按预期工作
- c# - 监听 HTTP 和 HTTPS?- C#/ASP.NET/Kestrel
- ruby-on-rails - 无论输入如何,Rspec 测试始终通过
- python - 在 MySQLdb 游标的 SQL 语句中使用 %%s%
- python - Python列出自定义基数系统中的前n个条目
- go - 在 Go 语言中找不到提供包 ed25519 的模块
- java - gradle -version 显示为 gradle command not found
- sql - 变量声明取决于 getdate
- oop - 将 DTO 映射到域对象只是为了对其执行一些计算然后丢弃是否有意义?
- encoding - Rust 的 GStreamer 编辑服务 / 如何指定编码器设置