首页 > 解决方案 > 在 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);
    }
}

然后作为后续行动,他们问了我类似的问题

“抛出异常对这个函数的用户有什么责任?”

“你能用其他方式处理这件事吗?”

“你能优雅地处理它吗?”

我真的不知道他们在寻找/暗示什么。谁能告诉我我是否在这里遗漏了什么?

标签: c++error-handling

解决方案


检查异常的要求要求调用者捕获和处理异常,使他们的代码变得混乱,并且还增加了处理异常的处理开销。

还有其他一些方法可以返回而不引发异常。

  • 一个数的阶乘不能为零或负数,因此可以返回 0 或负整数(即“幻数”)来表示该阶乘不存在或找不到。类似地,如果输入太大而无法计算 a 范围内的阶乘int,您也可以返回这个无效值,或者将特定值设置为指示故障模式的值(例如 0 表示输入负数,-1 表示输入太大,-2 表示任何其他异常)。
  • 您可以更改方法签名以返回指向 a 的指针int并将逻辑设置为返回NULL以指示无结果(C 代码经典地填充了“调用后检查 null 以确保成功”逻辑)。如果找到阶乘,则返回一个指向int持有该值的指针,该值是使用在堆上创建的new
  • 您可以接受 ashort int作为输入参数,从而消除许多(但不是全部)阶乘太大而无法适应返回值的输入值。这不会完全解决问题,但每一点都有帮助。结合另一种方法,您可以进一步减少潜在的故障模式。

上面的第一个选项可以很优雅,因为它允许调用者以多种方式使用该值(例如,打印它,在进一步的数学运算中使用它)而无需输入非数字或无法处理的数字和。缺点是你可能会得到一个毫无意义的数字。在某些情况下,输出“建筑物中的楼层数:-1,成本:$-1”比在重要的演示中崩溃要好!类似的情况(在业务规则方面无效但可以处理数据,在这种情况下是指针)在超级马里奥兄弟中产生了著名的负世界错误!

最后一个值更加优雅,因为它有助于防止无效数据甚至到达函数。正如他们所说,垃圾进,垃圾出。


推荐阅读