能,但仅限于当前 try 块中抛出且未被更具体 catch 拦截的异常;不捕获信号、longjmp 或未定义行为导致的崩溃;必须置于 catch 列表末尾。

catch(...) 能捕获所有异常吗?
能,但仅限于当前 try 块中抛出的、未被更具体 catch 子句拦截的异常。它不捕获信号(如 SIGSEGV)、C 风格的 longjmp,也不处理未定义行为触发的崩溃(比如空指针解引用本身不会“抛异常”,而是直接终止)。
常见误解是把它当“万能兜底”,结果程序在 catch(...) 之外就崩了——那往往根本没进 try,或者异常发生在构造函数/析构函数里且未被传播出来。
catch(...) 必须放在 catch 列表最后
否则编译器报错:error: 'catch(...)' must be the last handler for its try block。C++ 规定异常匹配按顺序尝试,一旦前面的 catch 类型能匹配,后面的就不会执行。
典型写法:
立即学习“C++免费学习笔记(深入)”;
try {
risky_operation();
} catch (const std::exception& e) {
std::cerr << "std::exception: " << e.what() << "\n";
} catch (const char* msg) {
std::cerr << "C-string error: " << msg << "\n";
} catch (...) {
std::cerr << "Unknown exception caught\n";
}- 把
catch(...)放最前 = 永远只走它,其他catch形同虚设 - 漏掉
const std::exception&这类通用捕获,可能导致标准异常也被吞进...,失去错误细节
catch(...) 里无法获取异常对象信息
这是最大限制:你只知道“有异常”,但不知道是什么类型、什么内容。不能调用 what(),不能 dynamic_cast,甚至不能安全地 rethrow(除非确定上下文允许)。
可行做法:
- 仅用于日志记录 + 程序清理(如关闭文件、释放裸指针),然后调用
std::terminate()或std::abort() - 配合
std::current_exception()提取异常指针(需 C++11+),再用std::rethrow_exception()在别处处理 —— 但开销大,且不是所有平台完全支持 - 避免在库接口或长期运行服务中仅靠
catch(...)吞异常,这会让调用方彻底失联
析构函数里慎用 catch(...)
C++11 起析构函数默认是 noexcept 的。如果在析构中抛出异常又没被当场捕获,会直接调用 std::terminate()。此时加 catch(...) 看似保险,实则掩盖问题:
- 异常可能源于资源释放失败(如 close() 返回 -1),但
catch(...)后继续执行,导致状态不一致 - 若析构函数自己又抛新异常,而当前已有未处理异常(stack unwinding 中),
std::terminate()必然触发 - 更稳妥的做法:在析构中用
noexcept函数做清理,失败时记录日志但不抛异常
真正需要兜底的,是顶层 main() 或线程入口,而不是每个对象的析构逻辑。










