在C++ Builder中如何获取当前异常对象(替代ExceptObject)
在C++中获取当前被处理的异常对象
C++标准库没有提供类似Delphi ExceptObject()的全局函数来直接获取当前catch块中的异常对象,因为异常对象的生命周期仅局限于对应的catch处理上下文。以下是针对不同场景的解决方案:
1. 针对已知类型的异常(如std::exception)
最可靠、跨平台的方式是手动将异常对象传递给后续调用的函数,避免依赖平台特定API:
try { // 抛出异常 throw std::runtime_error("test error"); } catch (const std::exception& exc) { DoSomething(exc); // 直接传递异常引用 } void DoSomething(const std::exception& exc) { // 在这里直接使用exc对象 std::cout << exc.what() << std::endl; }
2. 针对catch(...)的未知类型异常
这种场景下无法直接获取异常类型,需要结合平台特定API或C++11引入的std::exception_ptr:
方式一:使用std::exception_ptr(C++11及以上,跨平台)
在catch(...)中捕获异常指针,再传递给后续函数:
#include <exception> #include <stdexcept> try { throw std::runtime_error("unknown error"); } catch (...) { std::exception_ptr e_ptr = std::current_exception(); A3rdPartyCode(e_ptr); } void A3rdPartyCode(std::exception_ptr e_ptr) { MyCode(e_ptr); } void MyCode(std::exception_ptr e_ptr) { if (e_ptr) { try { std::rethrow_exception(e_ptr); // 重新抛出以获取具体类型 } catch (const std::exception& exc) { std::cout << exc.what() << std::endl; } catch (...) { // 处理非std::exception类型的异常 } } }
方式二:Windows平台特定API(MSVC编译器)
如果是Windows下的Native C++异常(结构化异常),可以使用GetExceptionInformation(),但注意该函数只能在__except块或catch块的直接上下文使用,若要传递到后续函数需要提前保存异常信息:
#include <windows.h> try { throw 123; } catch (...) { EXCEPTION_POINTERS* exp_ptr = GetExceptionInformation(); // 注意:exp_ptr仅在当前异常上下文有效,若要传递需复制相关数据 A3rdPartyCode(exp_ptr->ExceptionRecord->ExceptionCode); } void A3rdPartyCode(DWORD exc_code) { MyCode(exc_code); } void MyCode(DWORD exc_code) { // 根据异常码处理,比如EXCEPTION_ACCESS_VIOLATION等 std::cout << "Exception code: " << std::hex << exc_code << std::endl; }
注意事项
- 不要依赖非标准的全局异常获取函数,这类函数通常是编译器或平台特定的,迁移性差。
std::current_exception()只能在catch块内部调用,捕获后通过std::exception_ptr传递是跨平台的首选方案。
内容的提问来源于stack exchange,提问作者Александр Кулагин
相关产品推荐
相关产品推荐

