先抛出一个结论:能用 try-catch 捕获的,只有真正被 throw 抛出的 C++ 异常。 像空指针解引用、除零这类系统级错误,默认是不会触发 catch 的,除非编译器开启特定异常机制(比如 Windows 的 SEH 转换)。

看这张图,直观展示了 C++ 异常处理的边界:C++如何处理异常 _ try-catch捕获与throw用法【实战】

什么时候 catch 会完全失效?

很多人以为 catch(...) 能抓一切,真相远没那么简单。它只捕获 C++ 异常对象,对下面这些情况完全无感:

验证方法很简单:写个 throw 42; 能被捕获;但 *(int*)0 = 1; 会直接 crash,catch(...) 连运行的机会都没有。

throw 表达式必须匹配 catch 类型吗?

必须匹配,但规则比表面严格。不是“能转就行”,而是要求类型相同、公有继承、或有可调用的拷贝/移动构造函数:

核心建议:始终抛 std::exception 派生类,避免基础类型传递导致的切片或生命周期问题。

为什么 catch 参数推荐用引用?

值传递会触发异常对象拷贝,可能抛新异常(比如拷贝构造函数里 new 失败),导致栈展开中断、程序终止。看这个例子:

class BadCopy {public:    BadCopy() = default;    BadCopy(const BadCopy&) { throw std::runtime_error("copy failed"); }};// ...try {    throw BadCopy{};} catch(BadCopy b) { /* 这里会二次崩溃 */ }

正确写法只有一种:

资源泄漏风险:throw 发生在构造函数里怎么办?

构造函数中途 throw,已构造的成员会自动析构,但裸指针、文件描述符等不会。看个错例:

记住:C++ 异常安全的唯一可靠路径是 RAII,不是靠 try-catch 到处兜底。

话题回到最容易忽略的一点:noexcept 函数里如果意外抛出异常,程序会立刻调用 std::terminate,连 catch(...) 都来不及触发。检查第三方库接口是否标记 noexcept,比写 try 更关键。

本文转载于:https://www.php.cn/faq/2314072.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。