Swiftorial Logo
Home
Swift Lessons
Tutorials
Learn More
Career
Resources

Error Handling in C++

Introduction

Error handling is a critical aspect of writing robust and reliable software. In C++, error handling is typically done using exceptions. This tutorial will cover the basics of error handling in C++, how to use exceptions, and best practices to follow.

Basic Concepts

In C++, exceptions provide a way to react to exceptional circumstances (like runtime errors) in programs by transferring control to special functions called handlers. To use exceptions, you need to understand three keywords:

  • try: The block of code in which exceptions will be checked.
  • catch: The block of code that handles the exceptions.
  • throw: Used to throw an exception.

Using try, catch, and throw

Here is a simple example demonstrating the use of try, catch, and throw:

#include <iostream>

void checkAge(int age) {
    if (age < 18) {
        throw std::invalid_argument("Age must be 18 or older.");
    }
    std::cout << "Access granted." << std::endl;
}

int main() {
    try {
        checkAge(15);
    } catch (const std::invalid_argument& e) {
        std::cerr << "Caught exception: " << e.what() << std::endl;
    }
    return 0;
}

In this example, the checkAge function throws an exception if the provided age is less than 18. The main function catches and handles this exception.

Standard Exceptions

C++ provides a set of standard exceptions defined in the <stdexcept> header file. Some of the most commonly used standard exceptions are:

  • std::exception: Base class for all standard exceptions.
  • std::runtime_error: General runtime error.
  • std::logic_error: Logic errors such as violation of logical preconditions or class invariants.
  • std::invalid_argument: Invalid argument.
  • std::out_of_range: Out-of-range error.

These standard exceptions can be very useful for handling common error situations in a consistent manner.

Creating Custom Exceptions

Sometimes, the standard exceptions are not sufficient, and you may need to create your own custom exceptions. Here is how you can create and use a custom exception:

#include <iostream>
#include <exception>

class MyException : public std::exception {
public:
    const char* what() const noexcept override {
        return "Custom exception occurred";
    }
};

void functionThatThrows() {
    throw MyException();
}

int main() {
    try {
        functionThatThrows();
    } catch (const MyException& e) {
        std::cerr << "Caught exception: " << e.what() << std::endl;
    }
    return 0;
}

In this example, we define a custom exception MyException that inherits from std::exception. The what method is overridden to provide a custom error message.

Best Practices

Here are some best practices to follow when handling errors in C++:

  • Use Exceptions for Exceptional Situations: Exceptions should be used for unexpected events, not for normal control flow.
  • Catch Exceptions by Reference: Always catch exceptions by reference to avoid slicing and unnecessary copying.
  • Provide Useful Error Messages: Ensure that exceptions provide meaningful error messages to help with debugging.
  • Clean Up Resources: Use RAII (Resource Acquisition Is Initialization) to ensure that resources are properly cleaned up in the event of an exception.
  • Avoid Catch-All Handlers: Avoid using catch-all handlers (catching by ...) as they can make debugging difficult.

Conclusion

Effective error handling is essential for writing robust and reliable C++ programs. By understanding and using exceptions properly, you can handle errors gracefully and ensure that your programs behave as expected even in the face of unexpected situations.