You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ catch作用域内抛出派生类未被捕获的问题原因及修复

问题原因
  • C++的异常捕获遵循作用域匹配规则:一组catch仅能捕获其前面对应try代码块内抛出的异常。你代码中throw PE是在第一个catch块内部触发的,已经脱离了外层try的作用范围,同层级后续的catch (subEx e)不会响应该异常,异常会直接向上层栈展开寻找匹配的异常处理逻辑,没有对应处理就会触发程序强制终止。
  • 额外补充:即便你调换两个catch的顺序,把派生类的catch放在基类前面,也解决不了本次问题,核心原因是捕获范围不匹配。
修复方案

调整为嵌套try-catch结构,让内层catch抛出的异常可以被外层catch捕获,同时修复原代码的内存泄漏、析构逻辑缺失问题,可正常运行的代码如下:

#include <iostream>
#include <string>
using namespace std;

class myEx
{
    int errNum;
public:
    myEx(int e) : errNum(e) {}
    virtual void printErr() { cout << errNum << " "; }
    virtual ~myEx() {} // 新增虚析构函数,保证基类指针释放子类对象时逻辑正确
};
class subEx : public myEx
{
    string errDesc;
public:
    subEx(int e, string d) : myEx(e), errDesc(d) {}
    void printErr() override
    {
        myEx::printErr();
        cout << errDesc << " ";
    }
};
int main()
{
    try
    {
        try
        {
            myEx* pME = new subEx(0, "err 0");
            throw pME;
        }
        catch (myEx* p)
        {
            p->printErr();
            delete p; // 释放动态申请的内存,解决内存泄漏
            subEx PE(1, "err 1");
            throw PE;
        }
    }
    catch (const subEx& e) // 用const引用捕获避免对象拷贝,效率更高
    {
        e.printErr();
    }
    return 0;
}

核心修改点

  • 新增外层try块包裹原有整段逻辑,把原来的第二个catch移动到外层try对应的捕获位置,匹配内层catch抛出的subEx对象
  • 补充基类虚析构函数和内存释放逻辑,避免内存泄漏
  • 调整subEx捕获改用printErr新增override关键字,提升代码可读性与可维护性

内容的提问来源于stack exchange,提问作者Ronyco123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 15:21:01