C++ Exception Handling | try, catch, throw, User-defined Exceptions, noexcept


This complete tutorial on C++ Exception Handling explains how to handle runtime errors safely using try, catch, and throw. It also covers multiple catch blocks, user-defined exceptions, and the noexcept keyword. Following best practices, it helps learners write robust and fault-tolerant C++ programs.

Exception Handling – Complete Tutorial

1. What is Exception Handling?

Exception handling allows a program to respond to runtime errors gracefully, without crashing.

  1. Separates normal code from error handling code
  2. Provides control over unexpected situations

2. try, catch, throw

  1. try – block of code where exceptions might occur
  2. throw – used to signal an exception
  3. catch – handles the thrown exception

Example:


#include <iostream>
using namespace std;

int main() {
try {
int x = 10, y = 0;
if(y == 0) throw "Division by zero!";
cout << x/y << endl;
}
catch(const char* e) {
cout << "Error: " << e << endl;
}
}

3. Multiple Catch Blocks

You can have multiple catch blocks to handle different exception types.

Example:


try {
int x = -1;
if(x < 0) throw x; // integer exception
else throw "Negative"; // string exception
}
catch(int e) {
cout << "Integer exception: " << e << endl;
}
catch(const char* e) {
cout << "String exception: " << e << endl;
}

Key Points:

  1. Catch blocks are checked in order
  2. Most specific exception type should come first

4. User-Defined Exceptions

You can create custom exception classes to provide meaningful error messages.

Example:


#include <iostream>
#include <exception>
using namespace std;

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

int main() {
try {
throw MyException();
}
catch(const MyException &e) {
cout << e.what() << endl;
}
}

Notes:

  1. Derive from std::exception for compatibility
  2. Override what() for descriptive messages

5. noexcept

noexcept indicates that a function does not throw exceptions.

Example:


void safeFunc() noexcept {
cout << "This function does not throw" << endl;
}

int main() {
safeFunc();
}

Benefits:

  1. Helps compiler optimization
  2. Provides guarantee of exception safety

Best Practices

  1. Use exception handling for exceptional conditions, not normal logic
  2. Catch exceptions by reference to avoid slicing
  3. Always provide descriptive messages
  4. Prefer standard exceptions where possible (std::runtime_error, std::out_of_range)
  5. Use noexcept for functions that guarantee no exceptions

Common Mistakes

  1. Catching exceptions by value instead of reference
  2. Using exceptions for control flow
  3. Throwing built-in types instead of std::exception
  4. Ignoring memory/resource cleanup (use RAII to prevent leaks)

Summary

In this chapter, you learned about C++ Exception Handling, including:

  1. try, catch, and throw syntax
  2. Handling multiple exception types
  3. Creating user-defined exceptions
  4. Using noexcept for safe functions

Exception handling helps write robust, maintainable, and safe C++ programs by properly managing runtime errors.