C++ Custom Exception Classes
In C++, custom exception classes provide a way to define specific error types for domain-specific scenarios. While the standard exceptions in the C++ Standard Library, such as std::runtime_error
and std::logic_error
, cover many general-purpose use cases, custom exceptions enable developers to create more descriptive and context-specific error handling mechanisms.
Creating Custom Exception Classes
To create a custom exception class, you can define a class that inherits from std::exception
or its derived classes (e.g., std::runtime_error
). Overriding the what()
method provides a description of the error.
Basic Syntax for a Custom Exception Class
#include <exception>
#include <string>
class CustomException : public std::exception {
std::string message;
public:
explicit CustomException(const std::string& msg) : message(msg) {}
const char* what() const noexcept override {
return message.c_str();
}
};
Examples of Custom Exception Classes
Example 1: Basic Custom Exception Class
This example demonstrates a simple custom exception class to handle specific errors.
#include <iostream>
#include <exception>
#include <string>
class InvalidInputException : public std::exception {
std::string message;
public:
explicit InvalidInputException(const std::string& msg) : message("Invalid Input: " + msg) {}
const char* what() const noexcept override {
return message.c_str();
}
};
int main() {
try {
int input = -1;
if (input < 0)
throw InvalidInputException("Negative numbers are not allowed.");
} catch (const InvalidInputException& e) {
std::cerr << e.what() << std::endl;
}
return 0;
}
Working of this Program:
- Include necessary headers:
<iostream>
: Used for input/output operations.<exception>
: Provides the basestd::exception
class.<string>
: Used for thestd::string
class to handle string operations.
- Define a custom exception class:
- The class
InvalidInputException
inherits fromstd::exception
. - It has a private member variable
message
to store the custom error message. - The constructor takes a
std::string
parameter, prepends the text"Invalid Input: "
, and stores the result inmessage
. - The
what()
function is overridden to return the custom error message. It returns a C-string usingmessage.c_str()
and is marked asnoexcept
to indicate it doesn’t throw exceptions.
- The class
- Throw the custom exception:
- The variable
input
is initialized to-1
. - An
if
statement checks ifinput
is less than0
. - If the condition is true, an
InvalidInputException
is thrown with the message"Negative numbers are not allowed."
.
- The variable
- Handle the exception:
- The
try
block contains the code that may throw an exception. - The
catch
block captures exceptions of typeInvalidInputException
. - The custom error message is displayed using
std::cerr
and thewhat()
function of the exception.
- The
- Output the result:
- Since
input
is-1
, theif
condition is true, and an exception is thrown with the message"Negative numbers are not allowed."
. - The
catch
block captures this exception and outputs:"Invalid Input: Negative numbers are not allowed."
.
- Since
Output:
Invalid Input: Negative numbers are not allowed.
Example 2: Custom Exception with Additional Information
This example demonstrates a custom exception class that includes additional context, such as an error code.
#include <iostream>
#include <exception>
class FileException : public std::exception {
std::string filename;
std::string message;
public:
FileException(const std::string& file, const std::string& msg)
: filename(file), message("File Error [" + file + "]: " + msg) {}
const char* what() const noexcept override {
return message.c_str();
}
};
int main() {
try {
std::string file = "data.txt";
bool fileExists = false; // Simulating a missing file
if (!fileExists)
throw FileException(file, "File not found.");
} catch (const FileException& e) {
std::cerr << e.what() << std::endl;
}
return 0;
}
Output:
File Error [data.txt]: File not found.
Advantages of Custom Exception Classes
- Specificity: Allow precise identification of different error types.
- Contextual Information: Provide additional details about the error.
- Extensibility: Integrate seamlessly with existing error-handling frameworks.
Best Practices for Custom Exception Classes
- Inheritance: Inherit from
std::exception
or derived classes for better compatibility with existing error-handling mechanisms. - Contextual Information: Include relevant data (e.g., error codes, file names) to make debugging easier.
- Descriptive Messages: Provide clear and meaningful error messages.
- Noexcept: Ensure the
what()
method is marked withnoexcept
to prevent throwing exceptions during exception handling.
Conclusion
Custom exception classes in C++ provide a robust way to define and handle domain-specific errors. By inheriting from std::exception
, developers can create meaningful and descriptive exception types that improve code readability and debugging efficiency. Following best practices ensures that custom exceptions integrate seamlessly with standard error-handling mechanisms.