Hello everyone, I’m Liao Wang. Imagine that the world of programming is like a vast, boundless, and mysterious continent full of infinite possibilities, and C language is like a universal key that can help you unlock magical doors on this continent! When you decide to embark on your journey of C language programming and write your first line of code, that is the horn of adventure! Today, I want to talk about C language knowledge and how to solve the problems of C++ exception handling mechanism and custom exception system, hoping this article can help learners of C language knowledge.
-
1. Overview of C++ Exception Handling Mechanism
-
• try – catch block
try { int a = 10; int b = 0; if (b == 0) { throw "Divisor cannot be 0"; // Throw an exception } int result = a / b; } catch (const char* msg) { std::cerr << "Error message: " << msg << std::endl; }
-
• When the code in the
<span>try</span>
block throws an exception, the program’s execution flow immediately jumps to the corresponding<span>catch</span>
block that can handle that exception. In the above example, when<span>b</span>
is 0, a<span>const char*</span>
type exception is thrown, which is then caught by the corresponding<span>catch</span>
block, and the code in the<span>catch</span>
block will handle this exception, which here is outputting an error message. -
• In C++, exception handling is mainly achieved through
<span>try - catch</span>
blocks. The<span>try</span>
block contains code that may throw exceptions. For example: -
• Exception Objects
-
• Exceptions can be any type of object, including basic data types, class objects, etc. For example, a custom class object can be thrown as an exception. When an exception is thrown, an exception object is actually created and passed to the
<span>catch</span>
block. -
• The lifecycle of the exception object starts from the point of throwing it, until the corresponding
<span>catch</span>
block ends. If the exception is not re-thrown in the<span>catch</span>
block, the exception object will be destroyed after the<span>catch</span>
block finishes execution. -
• Exception Matching
class Base {}; class Derived : public Base {}; try { Derived d; throw d; } catch (Base& b) { std::cout << "Caught base class reference type exception" << std::endl; } catch (Derived& d) { std::cout << "Caught derived class reference type exception" << std::endl; }
-
• In this example, when a
<span>Derived</span>
class object is thrown, it will first match the<span>catch</span>
block of type<span>Derived</span>
. If there is no<span>catch</span>
block of type<span>Derived</span>
, it will match the<span>Base</span>
type (because<span>Derived</span>
is a derived class of<span>Base</span>
)<span>catch</span>
block. -
•
<span>catch</span>
blocks are checked in the order they appear in the code to find a matching<span>catch</span>
block for the thrown exception type. The matching rules are based on types, including exact matches, base-derived class matches, etc. For example, if a derived class object exception is thrown, it can be caught by the<span>catch</span>
block of that derived class or its base class. -
• Consider the following code:
2. Custom Exception System
-
• Why Custom Exception System
-
• The C++ Standard Library provides some basic exception types, such as
<span>std::runtime_error</span>
,<span>std::logic_error</span>
, etc., but in practical applications, these may not meet specific needs. For example, in a complex graphics processing program, it may be necessary to define specialized exception types for different graphic errors (such as point coordinate errors, graphic rendering errors, etc.). -
• How to Build a Custom Exception System
class MyException : public std::runtime_error { public: MyException(const char* msg) : std::runtime_error(msg) {} };
class FileError : public std::runtime_error { public: FileError(const char* msg) : std::runtime_error(msg) {} }; class FileOpenError : public FileError { public: FileOpenError(const char* msg) : FileError(msg) {} }; class FileReadError : public FileError { public: FileReadError(const char* msg) : FileError(msg) {} }; class FileWriteError : public FileError { public: FileWriteError(const char* msg) : FileError(msg) {} };
void openFile(const char* filename) { // Assume this is the code to open a file if (unable to open file) { throw FileOpenError("Unable to open file"); } }
try { openFile("test.txt"); } catch (FileOpenError& foe) { std::cerr << "File open error: " << foe.what() << std::endl; } catch (FileError& fe) { std::cerr << "File error: " << fe.what() << std::endl; } catch (std::runtime_error& re) { std::cerr << "Runtime error: " << re.what() << std::endl; } catch (std::exception& e) { std::cerr << "Standard exception: " << e.what() << std::endl; }
-
• This hierarchical exception handling approach makes the code more robust and easier to maintain, as different types of errors can be handled differently, and more general exception types can be caught in higher-level
<span>catch</span>
blocks. To install Sympy is relatively simple. You can use the following command: -
• In the places where the
<span>openFile</span>
function is called, you can use<span>try - catch</span>
blocks to catch and handle these exceptions: -
• When an error occurs in file processing code, the corresponding exception can be thrown. For example:
-
• This creates a custom exception class named
<span>MyException</span>
that inherits from<span>std::runtime_error</span>
. In the constructor, the base class constructor is called to pass the error message. -
• Exception Class Hierarchy: You can build a hierarchy of exception classes to better organize and classify exceptions. For example, suppose there is a file processing system, there might be
<span>FileOpenError</span>
,<span>FileReadError</span>
,<span>FileWriteError</span>
, etc., which can all derive from a<span>FileError</span>
base class. -
• Inherit from Standard Exception Classes: You can create custom exception classes by inheriting from
<span>std::exception</span>
class or its derived classes (like<span>std::runtime_error</span>
,<span>std::logic_error</span>
).I hope this can help everyone. If anyone has better methods, feel free to leave comments for discussion. This concludes the article on how to solve C++ exception handling mechanism and custom exception system.
Note: For reference only