MST

星途 面试题库

面试题:C++ 中析构函数异常处理的常规做法

在 C++ 中,如果析构函数中可能抛出异常,简述常规的异常处理方式以及为什么不能让析构函数轻易抛出异常。
26.2万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

常规异常处理方式

  1. 捕获异常并处理:在析构函数内部使用try - catch块捕获可能抛出的异常,并在catch块中进行相应处理,如记录日志、进行恢复操作等,避免异常传播出析构函数。例如:
class MyClass {
public:
    ~MyClass() {
        try {
            // 可能抛出异常的代码
        } catch(...) {
            // 处理异常,如记录日志
        }
    }
};
  1. 设置标志位:在可能抛出异常的操作之前设置标志位,若操作成功则清除标志位,析构函数根据标志位决定是否执行可能抛出异常的代码,从而避免异常。

不能让析构函数轻易抛出异常的原因

  1. 资源泄漏风险:当析构函数抛出异常时,如果该异常没有被捕获,程序会调用std::terminate从而终止程序。这可能导致对象所占用的资源无法正常释放,进而造成资源泄漏。例如,若对象持有文件句柄、内存指针等资源,在析构函数异常终止时,这些资源无法得到妥善处理。
  2. 异常安全问题:C++ 异常处理机制依赖于栈展开。如果析构函数抛出异常,在栈展开过程中又抛出新的异常,就会导致两个异常同时存在,这是 C++ 标准不允许的,会直接导致程序调用std::terminate
  3. 调用时机不确定性:析构函数在对象生命周期结束时自动调用,其调用时机可能是在其他异常处理过程中。若此时析构函数抛出异常,会干扰正在进行的异常处理流程,使得错误处理变得复杂且难以预料。