C++ Tutorial

Class and Object

Reference

Inheritance and Derivation

Polymorphism and Virtual Functions

Operator Overloading

Template

Exception

Object Oriented Advanced

Input/Output Stream

File Operations

Exception Types And Multi-level catch Matching in C++

In this tutorial, we'll discuss the different types of C++ exceptions and multi-level catch matching. C++ provides exception handling mechanisms that can be utilized to manage errors and unexpected behaviors during program execution.

  • C++ Exception Types:

C++ exceptions can be classified into the following categories:

a) Standard exceptions: C++ has a set of predefined exceptions derived from the std::exception class, such as std::logic_error, std::runtime_error, and their respective subclasses.

b) User-defined exceptions: Developers can create their own exception classes by inheriting from the std::exception class or its subclasses, and then add custom error messages or additional attributes as needed.

Here's a simple example of a user-defined exception class:

#include <stdexcept>
#include <string>

class CustomException : public std::runtime_error {
public:
    CustomException(const std::string &message) : std::runtime_error(message) {}
};
  • Multi-level catch matching:

C++ allows multiple catch blocks to handle exceptions in a hierarchical manner. Catch blocks are matched based on the type of exception thrown. This is particularly useful when there are base and derived classes, allowing you to catch both general and specific exceptions.

Here's an example of multi-level catch matching:

#include <iostream>
#include <stdexcept>
#include <string>

class CustomException : public std::runtime_error {
public:
    CustomException(const std::string &message) : std::runtime_error(message) {}
};

void func() {
    // Throw a CustomException
    throw CustomException("This is a custom exception");
}

int main() {
    try {
        func();
    } catch (const CustomException &e) {
        std::cerr << "Caught CustomException: " << e.what() << std::endl;
    } catch (const std::runtime_error &e) {
        std::cerr << "Caught std::runtime_error: " << e.what() << std::endl;
    } catch (const std::exception &e) {
        std::cerr << "Caught std::exception: " << e.what() << std::endl;
    } catch (...) {
        std::cerr << "Caught an unknown exception" << std::endl;
    }

    return 0;
}

In this example, if the CustomException is thrown, the first catch block will handle it. If a more general std::runtime_error or std::exception is thrown, the second or third catch blocks will handle them, respectively. The last catch block (catch-all) is used to handle any other unknown exceptions.

It's essential to remember that catch blocks should be ordered from most specific to most general, to ensure proper handling of exceptions.

  1. Multi-level catch blocks in C++:

    • Description: Explains how to use multi-level catch blocks to handle different levels of exceptions in C++.
    • Example Code:
      #include <iostream>
      #include <stdexcept>
      
      int main() {
          try {
              // Code that may throw exceptions
              throw std::runtime_error("An error occurred");
          } catch (const std::exception& e) {
              std::cerr << "Caught exception: " << e.what() << std::endl;
          } catch (...) {
              std::cerr << "Unknown exception caught" << std::endl;
          }
      
          return 0;
      }
      
  2. Exception hierarchy in C++:

    • Description: Discusses the hierarchy of exception classes in C++ and how catch blocks can handle them.
    • Example Code:
      #include <iostream>
      #include <stdexcept>
      
      void processFile() {
          // Code that may throw file-related exceptions
          throw std::ios_base::failure("File operation failed");
      }
      
      int main() {
          try {
              processFile();
          } catch (const std::exception& e) {
              std::cerr << "Caught exception: " << e.what() << std::endl;
          }
      
          return 0;
      }
      
  3. Matching multiple exception types in C++ catch blocks:

    • Description: Demonstrates how to catch multiple exception types using a single catch block in C++.
    • Example Code:
      #include <iostream>
      #include <stdexcept>
      
      int main() {
          try {
              // Code that may throw exceptions
              throw std::logic_error("Logic error occurred");
          } catch (const std::exception& e) {
              std::cerr << "Caught exception: " << e.what() << std::endl;
          }
      
          return 0;
      }
      
  4. Custom exception classes in C++:

    • Description: Illustrates the creation and usage of custom exception classes in C++.
    • Example Code:
      #include <iostream>
      #include <stdexcept>
      
      class CustomException : public std::exception {
      public:
          const char* what() const noexcept override {
              return "Custom exception occurred";
          }
      };
      
      int main() {
          try {
              // Code that may throw custom exceptions
              throw CustomException();
          } catch (const std::exception& e) {
              std::cerr << "Caught exception: " << e.what() << std::endl;
          }
      
          return 0;
      }
      
  5. Nested catch blocks in C++:

    • Description: Explains how to use nested catch blocks to handle exceptions at different levels in C++.
    • Example Code:
      #include <iostream>
      #include <stdexcept>
      
      int main() {
          try {
              try {
                  // Code that may throw exceptions
                  throw std::runtime_error("Inner exception");
              } catch (const std::exception& inner) {
                  std::cerr << "Inner exception: " << inner.what() << std::endl;
                  throw; // Rethrow the inner exception
              }
          } catch (const std::exception& outer) {
              std::cerr << "Outer exception: " << outer.what() << std::endl;
          }
      
          return 0;
      }
      
  6. C++ catching base and derived exceptions:

    • Description: Shows how catch blocks can handle both base and derived exceptions in C++.
    • Example Code:
      #include <iostream>
      #include <stdexcept>
      
      class DerivedException : public std::runtime_error {
      public:
          explicit DerivedException(const char* msg) : std::runtime_error(msg) {}
      };
      
      int main() {
          try {
              // Code that may throw exceptions
              throw DerivedException("Derived exception");
          } catch (const std::exception& e) {
              std::cerr << "Caught exception: " << e.what() << std::endl;
          }
      
          return 0;
      }
      
  7. Exception types and polymorphism in C++:

    • Description: Explores how polymorphism allows catch blocks to handle various exception types in C++.
    • Example Code:
      #include <iostream>
      #include <stdexcept>
      
      class BaseException : public std::exception {
      public:
          const char* what() const noexcept override {
              return "Base exception occurred";
          }
      };
      
      class DerivedException : public BaseException {
      public:
          const char* what() const noexcept override {
              return "Derived exception occurred";
          }
      };
      
      int main() {
          try {
              // Code that may throw exceptions
              throw DerivedException();
          } catch (const BaseException& e) {
              std::cerr << "Caught exception: " << e.what() << std::endl;
          }
      
          return 0;
      }
      
  8. Handling standard exceptions in multi-level catch in C++:

    • Description: Handles standard exceptions at different levels using multi-level catch blocks in C++.
    • Example Code:
      #include <iostream>
      #include <stdexcept>
      
      int main() {
          try {
              try {
                  // Code that may throw exceptions
                  throw std::invalid_argument("Invalid argument");
              } catch (const std::exception& inner) {
                  std::cerr << "Inner exception: " << inner.what() << std::endl;
                  throw; // Rethrow the inner exception
              }
          } catch (const std::exception& outer) {
              std::cerr << "Outer exception: " << outer.what() << std::endl;
          }
      
          return 0;
      }
      
  9. C++ exception specifications and catch clauses:

    • Description: Introduces exception specifications and their usage with catch clauses in C++.
    • Example Code:
      #include <iostream>
      #include <stdexcept>
      
      void mayThrowException() noexcept(false) {
          throw std::runtime_error("Exception from mayThrowException");
      }
      
      int main() {
          try {
              mayThrowException();
          } catch (const std::exception& e) {
              std::cerr << "Caught exception: " << e.what() << std::endl;
          }
      
          return 0;
      }
      
  10. User-defined exception classes and catch blocks in C++:

    • Description: Demonstrates the use of user-defined exception classes and catch blocks in C++.
    • Example Code:
      #include <iostream>
      #include <stdexcept>
      
      class CustomException : public std::exception {
      public:
          const char* what() const noexcept override {
              return "Custom exception occurred";
          }
      };
      
      int main() {
          try {
              // Code that may throw custom exceptions
              throw CustomException();
          } catch (const CustomException& e) {
              std::cerr << "Caught custom exception: " << e.what() << std::endl;
          } catch (const std::exception& e) {
              std::cerr << "Caught exception: " << e.what() << std::endl;
          }
      
          return 0;
      }
      
  11. C++ rethrowing exceptions in multi-level catch:

    • Description: Covers the concept of rethrowing exceptions within multi-level catch blocks in C++.
    • Example Code:
      #include <iostream>
      #include <stdexcept>
      
      int main() {
          try {
              try {
                  // Code that may throw exceptions
                  throw std::runtime_error("Inner exception");
              } catch (const std::exception& inner) {
                  std::cerr << "Inner exception: " << inner.what() << std::endl;
                  throw; // Rethrow the inner exception
              }
          } catch (const std::exception& outer) {
              std::cerr << "Outer exception: " << outer.what() << std::endl;
          }
      
          return 0;
      }
      
  12. C++ exception types and error reporting:

    • Description: Discusses different types of C++ exceptions and their role in error reporting.
    • Example Code:
      #include <iostream>
      #include <stdexcept>
      
      int main() {
          try {
              // Code that may throw exceptions
              throw std::runtime_error("An error occurred");
          } catch (const std::exception& e) {
              std::cerr << "Caught exception: " << e.what() << std::endl;
          }
      
          return 0;
      }
      
  13. Examples of multi-level catch matching in C++:

    • Description: Provides additional examples of handling exceptions at different levels using multi-level catch blocks in C++.
    • Example Code:
      #include <iostream>
      #include <stdexcept>
      
      int main() {
          try {
              try {
                  // Code that may throw exceptions
                  throw std::logic_error("Inner logic error");
              } catch (const std::exception& inner) {
                  std::cerr << "Inner exception: " << inner.what() << std::endl;
                  throw; // Rethrow the inner exception
              }
          } catch (const std::exception& outer) {
              std::cerr << "Outer exception: " << outer.what() << std::endl;
          }
      
          return 0;
      }