MST

星途 面试题库

面试题:C++异常处理中的异常规格说明

在C++中,曾经有异常规格说明(如void func() throw(int, char)),但现在已弃用。请解释它的作用是什么,为什么会被弃用,以及现在有什么替代方案。
46.0万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

异常规格说明的作用

  1. 告知调用者:异常规格说明能让函数调用者提前知道该函数可能抛出哪些类型的异常。例如 void func() throw(int, char) 表明函数 func 可能抛出 intchar 类型的异常。这样调用者在调用该函数时可以针对性地编写 catch 块来捕获可能出现的异常,增强了代码的健壮性和可维护性。
  2. 强制函数实现者:函数实现者必须遵守异常规格说明,如果函数内部抛出了不在规格说明中的异常类型,程序会调用 std::unexpected 函数,默认情况下 std::unexpected 会调用 std::terminate 终止程序。这有助于确保函数的异常行为是可预测的。

被弃用的原因

  1. 维护困难:当函数的实现细节发生变化,可能需要抛出新的异常类型时,不仅要修改函数内部代码,还需要同时更新异常规格说明。如果忘记更新异常规格说明,程序可能在运行时调用 std::unexpected 并终止,这增加了维护成本和出错的可能性。
  2. 缺乏灵活性:异常规格说明是一种静态的声明方式,无法适应运行时的动态情况。例如,根据不同的输入或运行环境,函数可能需要抛出不同类型的异常,而异常规格说明很难满足这种动态需求。
  3. 实际应用问题:在实际项目中,异常规格说明并没有得到广泛有效的使用。许多开发者发现它带来的好处不足以弥补其带来的复杂性和维护成本,导致很多代码并没有严格按照异常规格说明来编写和调用函数,使得这一特性的实用性大打折扣。

替代方案

  1. 文档说明:通过代码注释或独立的文档来描述函数可能抛出的异常类型。例如在函数定义上方添加注释 // func 可能抛出 std::runtime_error 异常。这种方式简单灵活,不需要修改代码的语法结构,维护起来相对容易。
  2. 异常类型体系:使用继承和多态构建合理的异常类型体系。例如,定义一个基类异常 std::exception,然后从它派生出自定义的异常类型,如 class MyException : public std::runtime_error。函数可以抛出这些派生类异常,调用者可以通过捕获基类异常来处理多种相关的异常情况,同时也可以通过捕获派生类异常来进行更具体的处理。这样在函数声明中不需要显式列出所有可能抛出的异常类型,增强了代码的灵活性和可维护性。