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
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.
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.
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.
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.
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; }
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; }
Throwing standard exceptions in C++:
<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; }
Handling different types of exceptions with throw
in C++:
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; }
Throwing exceptions in constructors and destructors in C++:
#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; }
Conditional throwing with throw
in C++:
#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; }
Rethrowing exceptions using throw
in C++:
#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; }
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; }
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; }
Using noexcept
with throw
in C++:
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; }