类成员函数间异常处理问题:f1未捕获f2抛出的异常触发终止错误
Alright, let's break down why your exception handling isn't working and how to fix it — I've stumbled on this exact gotcha before!
The core issue is in your f2() function's throw statement:
- You're using
throw;(or even justthrowwithout a semicolon/argument) in a context where there's no active exception. In C++, the no-argumentthrowis only meant to rethrow an exception that's currently being caught (inside acatchblock). When you use it outside of a catch context, it triggersstd::terminate()immediately — which is exactly the "Terminated without any active exception" error you're seeing. - This means the exception never even makes it up to
f1()'scatchblock; the program terminates the second that invalidthrowexecutes.
You need to throw a concrete exception object instead of using the no-argument throw. Here are two solid approaches:
1. Use a standard library exception
C++ provides a set of built-in exception types in the <stdexcept> header that cover most common cases. This is the simplest fix:
#include <stdexcept> // Don't forget this header! void O2::f2() { if (somestring.length() < 20) { // Throw a runtime_error with a descriptive message throw std::runtime_error("String length is less than the required 20 characters"); } } void O2::f1() { try { f2(); } catch (const std::exception& e) { // Catch standard exceptions (polymorphically) // Handle the error — you can even get the message with e.what() std::cerr << "Error caught: " << e.what() << std::endl; } catch (...) { // Optional: Catch-all for any unexpected exceptions std::cerr << "Unknown error occurred" << std::endl; } }
2. Define a custom exception type
If you want more control over your exception hierarchy (e.g., for distinguishing application-specific errors), you can create a custom exception class that inherits from std::exception:
#include <stdexcept> #include <string> class ShortStringException : public std::exception { private: std::string msg; public: explicit ShortStringException(const std::string& message) : msg(message) {} const char* what() const noexcept override { return msg.c_str(); } }; void O2::f2() { if (somestring.length() < 20) { throw ShortStringException("String is too short! Minimum length is 20."); } } void O2::f1() { try { f2(); } catch (const ShortStringException& e) { // Catch your custom exception first std::cerr << "Short string error: " << e.what() << std::endl; } catch (const std::exception& e) { // Catch other standard exceptions std::cerr << "Standard error: " << e.what() << std::endl; } }
Key takeaway
Never use throw; (no arguments) unless you're inside a catch block and want to rethrow the exception you just caught. Always throw a concrete exception object (either standard or custom) when you need to initiate an exception from scratch.
内容的提问来源于stack exchange,提问作者Naveen Nayana

