The exception handling mechanism of C++ is a structured method for handling program runtime errors. By separating normal logic from error handling code, the code is improved readability and maintainability. Here are detailed descriptions of its core components and working principles:
1. Three keywords for exception handling
1.1 try block
Function: The code segment that wraps the possible throwing of exceptions.
grammar:
try { // Code that may throw exceptions}
1.2 throw expression
Function: Throw an exception object (can be of any type, but usually inherited fromstd::exception
)。
grammar:
throw exception_object;
1.3 catch block
Function: Catch and handle specific types of exceptions.
grammar:
catch (ExceptionType1& e) { // Handle ExceptionType1 exception} catch (ExceptionType2& e) { // Handle ExceptionType2 exception} catch (...) { //Catch all exceptions // Handle unknown exceptions}
2. Exception handling process
Throw an exception: the code is executed to
throw
When , stop the current function immediately and start stack expansion (Stack Unwinding).-
Stack Expand:
Destruct local objects of the current scope (in reverse order of construction).
Find matching upward along the call chain
catch
piece.
Catch exception: Find the first match
catch
Execute its code after blocking.Uncaught exception: If no matching one is found
catch
Block, callstd::terminate()
Terminate the procedure.
3. Exception type and capture method
3.1 Standard exception class
The C++ standard library defines a set of exception classes (located at<stdexcept>
Header files), both inherited fromstd::exception
:
std::logic_error
: Program logic error (such asstd::invalid_argument
)。std::runtime_error
: Runtime error (such asstd::overflow_error
)。-
Custom exceptions are usually inherited from
std::exception
:class MyException : public std::exception { public: const char* what() const noexcept override { return "My custom exception"; } };
3.2 Capture method
Capture by value: Copy the exception object (may cause slicing problems).
Capture by reference: Avoid copying and preserve polymorphism (recommended).
Capture by pointer: Memory needs to be managed manually (not recommended).
Catch all exceptions:
catch (...)
(usually used for logging or resource cleaning).
4. Exceptional security
When an exception is thrown, a function needs to ensure that the resource does not leak, which is divided into three levels:
Basic Guarantee: After an exception occurs, the program is in a legal state.
Strong Guarantee: The operation is either completely successful or rolled back to the state before the operation (transaction semantics).
No-throw Guarantee: Promise not to throw any exceptions (using
noexcept
Tag).
5. Key mechanisms and precautions
5.1 noexcept keyword
Function: Declare the function to not throw exceptions, helping the compiler optimize the code.
-
grammar:
void func() noexcept; // C++11 rise
5.2 Stack expansion and destruction
RAII (Resource Acquisition Is Initialization): Depend on the destructor of the object automatically releases resources (such as smart pointers, file handles).
Avoid throwing exceptions in destructors: may cause program termination.
5.3 Performance impact
Zero overhead principle: when there is no exception, the code has no additional overhead.
Exceeding exceptions is expensive: it involves stack expansion and type matching, avoiding frequent use of general logic for exception handling.
6. Code example
6.1 Basic usage
#include <iostream> #include <stdexcept> void riskyOperation(int value) { if (value < 0) { throw std::invalid_argument("Value cannot be negative"); } // Other operations} int main() { try { riskyOperation(-5); } catch (const std::invalid_argument& e) { std::cerr << "Error: " << () << std::endl; } catch (...) { std::cerr << "Unknown error occurred" << std::endl; } return 0; }
6.2 Custom exceptions
#include <exception> #include <string> class NetworkError : public std::exception { private: std::string message; public: NetworkError(const std::string& msg) : message(msg) {} const char* what() const noexcept override { return message.c_str(); } }; void connectToServer() { throw NetworkError("Connection timeout"); }
7. Best Practices
Priority is given to the use of standard exception types to keep the exception hierarchy clear.
Catch exceptions by reference to avoid object slicing and polymorphism loss.
Use RAII management resources to ensure exceptional security.
Avoid throwing exceptions in the constructor unless resources can be completely cleaned.
use
noexcept
Tagging functions that do not throw exceptions, improving performance.
Summarize
C++ exception handling is passedtry
/catch
/throw
Provides a structured error management mechanism, combined with RAII and standard exception classes, which can effectively improve the robustness of the code. Rational use of exception handling requires weighing performance and security, and following exception security levels and best practices.
This is the end of this article about the exception handling mechanism in C++. For more related C++ exception handling content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!