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

throw Keyword (Throw Exception) in C++

In this tutorial, we will learn about the throw keyword in C++. The throw keyword is used to raise exceptions in your code, allowing you to handle errors or exceptional conditions gracefully. When an exception is thrown, the program control jumps to the nearest matching catch block, where you can handle the exception.

  • Basic usage of throw:

Here's a simple example demonstrating the use of the throw keyword:

#include <iostream>

double divide(double a, double b) {
    if (b == 0) {
        throw "Division by zero!";
    }
    return a / b;
}

int main() {
    try {
        std::cout << "Result: " << divide(10, 2) << std::endl; // Output: Result: 5
        std::cout << "Result: " << divide(10, 0) << std::endl;
    } catch (const char* e) {
        std::cerr << "Error: " << e << std::endl; // Output: Error: Division by zero!
    }

    return 0;
}

In this example, we define a divide() function that throws a const char* exception if the divisor (b) is zero. In the main() function, we use a try block to call the divide() function and a catch block to handle the exception.

  • Throwing exceptions of different types:

You can throw exceptions of any type, such as built-in types (e.g., int, double, const char*), objects, or even user-defined types:

#include <iostream>
#include <stdexcept>

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

void myFunction(int value) {
    if (value < 0) {
        throw CustomException("Negative value encountered!");
    } else if (value == 0) {
        throw std::runtime_error("Zero value encountered!");
    }
}

int main() {
    try {
        myFunction(-1);
    } catch (const CustomException& e) {
        std::cerr << "Custom exception caught: " << e.what() << std::endl; // Output: Custom exception caught: Negative value encountered!
    } catch (const std::runtime_error& e) {
        std::cerr << "Runtime exception caught: " << e.what() << std::endl;
    }

    return 0;
}

In this example, we define a CustomException class derived from std::runtime_error and a myFunction() function that throws exceptions of different types. In the main() function, we use separate catch blocks to handle each exception type.

  • Rethrowing exceptions:

You can rethrow an exception by using the throw keyword without any argument in a catch block. This can be useful if you want to perform some action in the current catch block and then let the exception be caught by an outer catch block:

#include <iostream>
#include <stdexcept>

void myFunction(int value) {
    if (value < 0) {
        throw std::runtime_error("Negative value encountered!");
    }
}

int main() {
    try {
        try {
            myFunction(-1);
        } catch (const std::runtime_error& e) {
            std::cerr << "Exception caught, rethrowing..." << std::endl;
            throw; // Rethrow the exception
        }
    } catch (const std::runtime_error& e) {
        std::cerr << "Outer catch block: " << e.what() << std::endl; // Output: Outer catch block: Negative value encountered!
    }

    return 0;
}

In this example, we define a myFunction() function that throws a std::runtime_error exception when the input value is negative. In the main() function, we use nested try blocks. In the inner catch block, we catch the exception, print a message, and then rethrow the exception. The outer catch block catches the rethrown exception and handles it.

Note that when you rethrow an exception, the original exception object is preserved, including its type and state. The rethrown exception can be caught by another catch block that matches its type.

  1. How to use throw to raise exceptions in C++:

    #include <iostream>
    #include <stdexcept>
    
    void exampleFunction() {
        // Using throw to raise an exception
        throw std::runtime_error("An error occurred.");
    }
    
    int main() {
        try {
            exampleFunction();
        } catch (const std::exception& e) {
            std::cerr << "Caught exception: " << e.what() << std::endl;
        }
    
        return 0;
    }
    
  2. Custom exception classes and throw in C++:

    #include <iostream>
    #include <stdexcept>
    
    class CustomException : public std::exception {
    public:
        const char* what() const noexcept override {
            return "Custom exception occurred.";
        }
    };
    
    void exampleFunction() {
        // Throwing a custom exception
        throw CustomException();
    }
    
    int main() {
        try {
            exampleFunction();
        } catch (const std::exception& e) {
            std::cerr << "Caught exception: " << e.what() << std::endl;
        }
    
        return 0;
    }
    
  3. Throwing standard exceptions in C++:

    • Standard exceptions are part of the <stdexcept> header and provide common exception types.
    #include <iostream>
    #include <stdexcept>
    
    void exampleFunction() {
        // Throwing a standard exception
        throw std::invalid_argument("Invalid argument");
    }
    
    int main() {
        try {
            exampleFunction();
        } catch (const std::exception& e) {
            std::cerr << "Caught exception: " << e.what() << std::endl;
        }
    
        return 0;
    }
    
  4. Handling different types of exceptions with throw in C++:

    • Multiple catch blocks can be used to handle different types of exceptions.
    #include <iostream>
    #include <stdexcept>
    
    void exampleFunction(int value) {
        if (value < 0) {
            throw std::out_of_range("Value out of range");
        } else if (value == 0) {
            throw std::runtime_error("Zero is not allowed");
        }
    }
    
    int main() {
        try {
            exampleFunction(-1);
        } catch (const std::out_of_range& e) {
            std::cerr << "Out of range: " << e.what() << std::endl;
        } catch (const std::runtime_error& e) {
            std::cerr << "Runtime error: " << e.what() << std::endl;
        }
    
        return 0;
    }
    
  5. Throwing exceptions in constructors and destructors in C++:

    • Exceptions can be thrown from constructors or destructors to signal initialization or cleanup failure.
    #include <iostream>
    #include <stdexcept>
    
    class MyClass {
    public:
        MyClass() {
            // Throw an exception in the constructor
            throw std::runtime_error("Constructor failed");
        }
    
        ~MyClass() {
            // Throw an exception in the destructor
            throw std::runtime_error("Destructor failed");
        }
    };
    
    int main() {
        try {
            MyClass obj;  // Exception thrown in the constructor
        } catch (const std::exception& e) {
            std::cerr << "Caught exception: " << e.what() << std::endl;
        }
    
        return 0;
    }
    
  6. Conditional throwing with throw in C++:

    • Use conditional statements to determine when to throw an exception.
    #include <iostream>
    #include <stdexcept>
    
    void exampleFunction(int value) {
        if (value < 0) {
            throw std::out_of_range("Value out of range");
        }
    }
    
    int main() {
        int userInput;
        std::cout << "Enter a positive number: ";
        std::cin >> userInput;
    
        try {
            exampleFunction(userInput);
        } catch (const std::out_of_range& e) {
            std::cerr << "Out of range: " << e.what() << std::endl;
        }
    
        return 0;
    }
    
  7. Rethrowing exceptions using throw in C++:

    • Rethrowing allows an exception to be caught, processed, and then rethrown for further handling.
    #include <iostream>
    #include <stdexcept>
    
    void processFile() {
        try {
            // Code that may throw an exception
            throw std::runtime_error("Error processing file");
        } catch (const std::exception& e) {
            std::cerr << "Caught exception: " << e.what() << std::endl;
            // Rethrow the exception
            throw; 
        }
    }
    
    int main() {
        try {
            processFile();
        } catch (const std::exception& e) {
            std::cerr << "Main caught exception: " << e.what() << std::endl;
        }
    
        return 0;
    }
    
  8. Throwing exceptions in user-defined functions in C++:

    #include <iostream>
    #include <stdexcept>
    
    void customFunction() {
        // Throwing an exception in a user-defined function
        throw std::logic_error("Custom function exception");
    }
    
    int main() {
        try {
            customFunction();
        } catch (const std::exception& e) {
            std::cerr << "Caught exception: " << e.what() << std::endl;
        }
    
        return 0;
    }
    
  9. Throwing exceptions in class methods in C++:

    #include <iostream>
    #include <stdexcept>
    
    class MyClass {
    public:
        void throwError() {
            // Throwing an exception in a class method
            throw std::runtime_error("Error in class method");
        }
    };
    
    int main() {
        try {
            MyClass obj;
            obj.throwError();
        } catch (const std::exception& e) {
            std::cerr << "Caught exception: " << e.what() << std::endl;
        }
    
        return 0;
    }
    
  10. Using noexcept with throw in C++:

    • The noexcept specifier is used to indicate that a function does not throw exceptions.
    #include <iostream>
    
    void noExceptionFunction() noexcept {
        // Function without throwing exceptions
        std::cout << "No exceptions here!" << std::endl;
    }
    
    int main() {
        try {
            noExceptionFunction();
        } catch (...) {
            std::cerr << "This block won't catch exceptions from noExceptionFunction()" << std::endl;
        }
    
        return 0;
    }