C++ - Try and Catch

Try and Catch in C++

Introduction

In C++, error handling is done using exceptions, which are special objects used to handle errors or unusual situations that may arise during the execution of a program. The try and catch blocks are used to handle exceptions. The try block contains code that might throw an exception, and the catch block is used to handle the exception.

Syntax of Try and Catch

The basic syntax of try and catch is as follows:


try {
    // Code that may throw an exception
} catch (exception_type e) {
    // Code to handle the exception
}
    

The try block contains the code that might generate an exception. If an exception occurs, the flow of execution jumps to the catch block, where you can handle the error appropriately.

Working with Exceptions

Exceptions are thrown using the throw keyword. Once an exception is thrown, the control jumps to the nearest matching catch block. If no matching catch block is found, the program terminates.

Code Example - Throw and Catch an Exception


#include 
#include 
using namespace std;

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

int main() {
    int x = 10, y = 0;
    try {
        cout << "Result: " << divide(x, y) << endl;
    } catch (const runtime_error& e) {
        cout << "Caught exception: " << e.what() << endl;
    }
    return 0;
}
    

In this example, the divide function checks if the divisor is zero. If it is, it throws a runtime_error exception, which is caught in the catch block in the main> function.

Multiple Catch Blocks

You can use multiple catch blocks to handle different types of exceptions. Each catch block can handle a different exception type or the same type with different exception parameters.

Code Example - Multiple Catch Blocks


#include 
#include 
using namespace std;

void checkValue(int value) {
    if (value < 0) {
        throw invalid_argument("Negative value not allowed!");
    }
    if (value == 0) {
        throw runtime_error("Zero value error!");
    }
    cout << "Value is: " << value << endl;
}

int main() {
    int num = -5;
    try {
        checkValue(num);
    } catch (const invalid_argument& e) {
        cout << "Caught exception: " << e.what() << endl;
    } catch (const runtime_error& e) {
        cout << "Caught exception: " << e.what() << endl;
    }
    return 0;
}
    

In this example, there are two catch blocks: one for handling invalid_argument exceptions and the other for handling runtime_error exceptions. The exception thrown will match the appropriate catch block.

Catch-All Block

In C++, you can use a "catch-all" block to catch any type of exception that is not specifically handled by previous catch blocks. This is done by using an ellipsis (catch(...)) as a catch block.

Code Example - Catch-All Block


#include 
#include 
using namespace std;

int main() {
    try {
        throw "This is a string exception!";
    } catch (const char* msg) {
        cout << "Caught exception: " << msg << endl;
    } catch (...) {
        cout << "Caught an unknown exception!" << endl;
    }
    return 0;
}
    

In this example, the catch(...) block catches any exceptions that are not specifically handled by other catch blocks.

Exception Propagation

If an exception is not caught in the current function, it is propagated (or "bubbled") up to the calling function. This process continues until the exception is caught or the program terminates.

Code Example - Exception Propagation


#include 
#include 
using namespace std;

void functionB() {
    throw runtime_error("Error in functionB");
}

void functionA() {
    functionB();  // Exception will be propagated
}

int main() {
    try {
        functionA();
    } catch (const runtime_error& e) {
        cout << "Caught exception: " << e.what() << endl;
    }
    return 0;
}
    

In this example, the exception thrown in functionB is propagated up to functionA and then caught in the main function.

Re-throwing Exceptions

In some cases, after catching an exception, you may want to re-throw it to allow it to be handled elsewhere. This can be done using the throw keyword inside the catch block.

Code Example - Re-throwing an Exception


#include 
#include 
using namespace std;

void functionA() {
    try {
        throw runtime_error("Error in functionA");
    } catch (const runtime_error& e) {
        cout << "Caught exception in functionA: " << e.what() << endl;
        throw;  // Re-throw the exception
    }
}

int main() {
    try {
        functionA();
    } catch (const runtime_error& e) {
        cout << "Caught exception in main: " << e.what() << endl;
    }
    return 0;
}
    

In this example, after catching the exception in functionA, it is re-thrown and caught in the main function.

The try and catch mechanism in C++ provides a powerful way to handle runtime errors and exceptions in a controlled manner. By using exceptions, you can ensure that your program can handle unexpected situations gracefully without crashing. Understanding how to throw, catch, and propagate exceptions will help you build more robust and error-resistant programs.

logo

C++

Beginner 5 Hours

Try and Catch in C++

Introduction

In C++, error handling is done using exceptions, which are special objects used to handle errors or unusual situations that may arise during the execution of a program. The try and catch blocks are used to handle exceptions. The try block contains code that might throw an exception, and the catch block is used to handle the exception.

Syntax of Try and Catch

The basic syntax of try and catch is as follows:

try { // Code that may throw an exception } catch (exception_type e) { // Code to handle the exception }

The try block contains the code that might generate an exception. If an exception occurs, the flow of execution jumps to the catch block, where you can handle the error appropriately.

Working with Exceptions

Exceptions are thrown using the throw keyword. Once an exception is thrown, the control jumps to the nearest matching catch block. If no matching catch block is found, the program terminates.

Code Example - Throw and Catch an Exception

#include #include using namespace std; int divide(int a, int b) { if (b == 0) { throw runtime_error("Division by zero error!"); } return a / b; } int main() { int x = 10, y = 0; try { cout << "Result: " << divide(x, y) << endl; } catch (const runtime_error& e) { cout << "Caught exception: " << e.what() << endl; } return 0; }

In this example, the divide function checks if the divisor is zero. If it is, it throws a runtime_error exception, which is caught in the catch block in the main> function.

Multiple Catch Blocks

You can use multiple catch blocks to handle different types of exceptions. Each catch block can handle a different exception type or the same type with different exception parameters.

Code Example - Multiple Catch Blocks

#include #include using namespace std; void checkValue(int value) { if (value < 0) { throw invalid_argument("Negative value not allowed!"); } if (value == 0) { throw runtime_error("Zero value error!"); } cout << "Value is: " << value << endl; } int main() { int num = -5; try { checkValue(num); } catch (const invalid_argument& e) { cout << "Caught exception: " << e.what() << endl; } catch (const runtime_error& e) { cout << "Caught exception: " << e.what() << endl; } return 0; }

In this example, there are two catch blocks: one for handling invalid_argument exceptions and the other for handling runtime_error exceptions. The exception thrown will match the appropriate catch block.

Catch-All Block

In C++, you can use a "catch-all" block to catch any type of exception that is not specifically handled by previous catch blocks. This is done by using an ellipsis (catch(...)) as a catch block.

Code Example - Catch-All Block

#include #include using namespace std; int main() { try { throw "This is a string exception!"; } catch (const char* msg) { cout << "Caught exception: " << msg << endl; } catch (...) { cout << "Caught an unknown exception!" << endl; } return 0; }

In this example, the catch(...) block catches any exceptions that are not specifically handled by other catch blocks.

Exception Propagation

If an exception is not caught in the current function, it is propagated (or "bubbled") up to the calling function. This process continues until the exception is caught or the program terminates.

Code Example - Exception Propagation

#include #include using namespace std; void functionB() { throw runtime_error("Error in functionB"); } void functionA() { functionB(); // Exception will be propagated } int main() { try { functionA(); } catch (const runtime_error& e) { cout << "Caught exception: " << e.what() << endl; } return 0; }

In this example, the exception thrown in functionB is propagated up to functionA and then caught in the main function.

Re-throwing Exceptions

In some cases, after catching an exception, you may want to re-throw it to allow it to be handled elsewhere. This can be done using the throw keyword inside the catch block.

Code Example - Re-throwing an Exception

#include #include using namespace std; void functionA() { try { throw runtime_error("Error in functionA"); } catch (const runtime_error& e) { cout << "Caught exception in functionA: " << e.what() << endl; throw; // Re-throw the exception } } int main() { try { functionA(); } catch (const runtime_error& e) { cout << "Caught exception in main: " << e.what() << endl; } return 0; }

In this example, after catching the exception in functionA, it is re-thrown and caught in the main function.

The try and catch mechanism in C++ provides a powerful way to handle runtime errors and exceptions in a controlled manner. By using exceptions, you can ensure that your program can handle unexpected situations gracefully without crashing. Understanding how to throw, catch, and propagate exceptions will help you build more robust and error-resistant programs.

Related Tutorials

Frequently Asked Questions for C++

A void pointer is a special type of pointer that can point to any data type, making it versatile for generic data handling.

Dynamic memory allocation in C++ refers to allocating memory at runtime using operators like new and delete, providing flexibility in memory management.

Templates in C++ allow functions and classes to operate with generic types, enabling code reusability and type safety.

Iterators are objects that allow traversal through the elements of a container in the STL, providing a uniform way to access elements.

C++ is an object-oriented programming language that extends C by adding features like classes, inheritance, and polymorphism. Unlike C, which is procedural, C++ supports both procedural and object-oriented paradigms.

An array in C++ is declared by specifying the type of its elements followed by the array name and size in square brackets, e.g., int arr[10];.

The new operator allocates memory dynamically on the heap, while the delete operator deallocates memory, preventing memory leaks.

Type casting in C++ is the process of converting a variable from one data type to another, either implicitly or explicitly.

Inheritance is a feature in C++ where a new class (derived class) acquires properties and behaviors (methods) from an existing class (base class).

Operator overloading enables the redefinition of the way operators work for user-defined types, allowing operators to be used with objects of those types.

Function overloading allows multiple functions with the same name but different parameters to coexist in a C++ program, enabling more intuitive function calls.

In C++, a class is declared using the class keyword, followed by the class name and a pair of curly braces containing member variables and functions.

No, a C++ program cannot execute without a main() function, as it is the designated entry point for program execution.

Vectors are dynamic arrays provided by the STL in C++ that can grow or shrink in size during program execution.

A namespace in C++ is a declarative region that provides a scope to the identifiers (names of types, functions, variables) to avoid name conflicts.

The primary difference is that members of a struct are public by default, whereas members of a class are private by default.

The const keyword in C++ is used to define constants, indicating that the value of a variable cannot be changed after initialization.

Exception handling in C++ is a mechanism to handle runtime errors using try, catch, and throw blocks, allowing a program to continue execution after an error.

The STL is a collection of template classes and functions in C++ that provide general-purpose algorithms and data structures like vectors, lists, and maps.

A reference in C++ is an alias for another variable, whereas a pointer holds the memory address of a variable. References cannot be null and must be initialized upon declaration.

Pointers in C++ are variables that store memory addresses of other variables. They allow for dynamic memory allocation and efficient array handling.

Polymorphism allows objects of different classes to be treated as objects of a common base class, enabling a single function or operator to work in different ways.

Constructors are special member functions that initialize objects when they are created. Destructors are called when objects are destroyed, used to release resources.

These access specifiers define the accessibility of class members. Public members are accessible from outside the class, private members are not, and protected members are accessible within the class and by derived classes.

The main() function serves as the entry point for a C++ program. It is where the execution starts and ends.

line

Copyrights © 2024 letsupdateskills All rights reserved