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

为何std::invalid_argument无法被catch(const std::exception& ex)捕获?

问题:为什么std::invalid_argument没被std::exception捕获反而触发catch(...)?

我写了下面这段代码,发现抛出的std::invalid_argument无法被catch(const std::exception &ex)块捕获,反而触发了catch(...)块。按道理std::invalid_argument继承自std::exception,应该被第一个捕获块处理才对,我到底忽略了什么细节?

void App::start() try {
    initialize();
    //...
    m_errorCode = 0;
} catch (const std::exception &ex) {
    std::cerr << ex.what() << '\n';
    m_errorCode = -1;
} catch (...) {
    std::cerr << "Unknown exception\n";
    m_errorCode = -2;
}

void App::initialize() {
    m_controller = createController();
    //...
}

std::unique_ptr<IController> App::createController() const {
    if (m_config.m_controllerType == "iot_v1") {
        return std::make_unique<ControllerIotV1>();
    }
    if (m_config.m_controllerType == "iot_v2") {
        return std::make_unique<ControllerIotV2>();
    }
    throw new std::invalid_argument("Unsupported controller type.");
}

哈哈,这个问题其实是个很容易踩的小坑!你在createController里抛出异常的方式错了——你用了throw new std::invalid_argument(...),这抛出的是一个指针(std::invalid_argument*类型),而不是std::invalid_argument对象本身。

你的第一个catch块捕获的是const std::exception &,也就是引用类型的异常对象,指针类型和引用类型完全不匹配,所以这个catch块根本认不出这个异常,只能让兜底的catch(...)来处理它。

解决方法很简单,把new去掉,直接抛出异常对象就行:

throw std::invalid_argument("Unsupported controller type.");

顺便提一句,C++里抛出异常几乎都是直接抛对象(或者临时对象),很少会抛指针——抛指针不仅会导致类型不匹配的问题,还会带来内存泄漏的风险:因为抛出的指针没人去delete的话,这块内存就永远释放不了了。直接抛对象的话,编译器会自动帮你处理异常对象的生命周期,完全不用操心内存的事。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:42:49