Tutorial Study Image

Exception Handling in C++


June 9, 2023, Learn eTutorial
253

Different types of failures, including those caused by incorrect input or coding faults made by the programmer, can happen when running C++ code.C++ often stops and produces an error message when something goes wrong. This is known as throwing an exception in C++ (which will throw an error).

What exactly do you mean by Exception Handling in C++?

Exception handling in C++ allows you to deal with unforeseen situations such as runtime errors. As a result, if an unexpected event happens, control of the program is passed to handlers, which are special functions.

You put a certain portion of the program code under exception inspection in order to catch the exceptions. The try-catch block contains the particular area of code.

An exception will be definitely thrown if an extraordinary situation happens within that area of code. The program will then pass control to the exception handler.

The code will run regularly if no unusual circumstances arise. The handlers will not be taken into consideration.

What is the need for exception handling in C++?

Exception handling in C++ is used for the following reasons:

  • Your error-handling code will be kept separate from your regular code. The code will be easier to read and maintain.
  • Functions have the flexibility to handle any exception. A function will only catch certain exceptions, even if it throws many. The caller is responsible for handling uncaught exceptions.

Keywords for Exception Handling in C++

throw: A program throws an exception when it runs across a problem. Throwing is facilitated via the throw keyword in a program.

catch: In order to handle an exception, a program utilizes an exception handler. It is inserted into the portion of a program where the problem must be handled. It is accomplished by the use of the catch keyword.

try: try identifies the section of code for which specific exceptions will be invoked. One or more catch blocks should be placed after it.

Assume that a code block will throw an exception. Through the use of try-and-catch keywords, the exception will be caught. The try/catch block should be placed around code that could throw an exception. Protected code is the term used to describe such code.

Syntax:

This is the syntax for the try/catch:


try {
   // the protected code
} catch( Exception_Name exception1 ) {
   // catch block
} catch( Exception_Name exception2 ) {
   // catch block
} catch( Exception_Name exceptionN ) {
   // catch block
}

 

Although we only have one try statement, we can have several catch statements. The exception to be caught has a name and it is the ExceptionName. Your defined names for referring to the exceptions are exception1, exception2, and exceptionN.

Examples for Exception Handling in C++

  1. The following is a basic C++ example of how to handle exceptions. The try/catch block execution flow is described in the program's output.

    The C++ example shows how to handle exceptions.

    
    #include <iostream>
    using namespace std;
    
    int main()
    {
    int x = -1;
    
    // Some code
    cout << "Before the try \n";
    try {
     cout << "Inside the try \n";
     if (x < 0)
     {
      throw x;
      cout << "After the throw (Never executed) \n";
     }
    }
    catch (int x ) {
     cout << "Exception Caught \n";
    }
    
    cout << "After catch (Will be executed) \n";
    return 0;
    }
    
     
    

    Output:

    
    Before the try 
    Inside the try 
    Exception Caught 
    After catch (Will be executed)
    
    
  2. To capture all exception types, there is a special catch block known as the "catch-all" block, expressed as catch(...). For instance, the catch(...) block will be run in the following program when an int is thrown as an exception because there isn't a catch block for int.

    Example program with catch-all

    
    #include <iostream>
    using namespace std;
    
    int main()
    {
     try {
     throw 10;
     }
     catch (char *excp) {
      cout << "Caught " << excp;
     }
     catch (...) {
      cout << "The Default Exception\n";
     }
     return 0;
    }
    
     
    

    Output:

    
    The Default Exception
    
  3. For primitive types, there is no implicit type conversion. For instance, "a" is not implicitly transformed to an int in the following program.

    
    #include <iostream>
    using namespace std;
    
    int main()
    {
     try {
     throw 'a';
     }
     catch (int x) {
      cout << "Caught " << x;
     }
     catch (...) {
      cout << " The Default Exception\n";
     }
     return 0;
    }
    
     
    

    Output:

    
    The Default Exception
    
  4. The program terminates abnormally if an exception is raised and not caught somewhere. For instance, a char is thrown in the program below but is not caught by a catch block.

    
    #include <iostream>
    using namespace std;
    
    int main()
    {
     try {
     throw 'a';
     }
     catch (int x) {
      cout << "Caught ";
     }
     return 0;
    }
    
     
    

    Output:

    
    terminate called after throwing an instance of 'char'
    timeout: the monitored command dumped core
    
  5. A base class exception should be handled after a derived class exception.

  6. The C++ library provides a standard exception class that serves as the root class for all standard exceptions, similar to how Java does. All objects which are thrown by standard library components are inherited from this class. Because of this, by catching this type, all common exceptions can be caught.

  7. In contrast to Java, all exceptions in C++ are unchecked, meaning that the compiler does not determine whether an exception is caught or not (See this for details). Therefore, it is not required to list all uncaught exceptions in a function definition. Nevertheless, doing so is a good idea.

    
    #include <iostream>
    using namespace std;
    
    // Here we mainly specify the exceptions that this function will
    // throws.
    void fun(int *ptr, int x) throw (int *, int) // Dynamic Exception specification
    {
     if (ptr == NULL)
      throw ptr;
     if (x == 0)
      throw x;
     /* Some functionality */
    }
    
    int main()
    {
     try {
     fun(NULL, 0);
     }
     catch(...) {
      cout << "Caught the exception from fun()";
     }
     return 0;
    }
    
     
    

    Output:

    
    Caught the exception from fun()
    
  8. In C++, try/catch blocks may be nested. Additionally, "throw;" can be used to rethrow an exception

    
    #include <iostream>
    using namespace std;
    
    int main()
    {
     try {
      try {
       throw 50;
      }
      catch (int n) {
       cout << "Handle Partially ";
       throw; // Re-throwing an exception
      }
     }
     catch (int n) {
      cout << "Handle remaining ";
     }
     return 0;
    }
    
     
    

    Output:

    
    Handle Partially Handle remaining
    
  9. When an exception is thrown, all objects created within the try block are destroyed before control is passed to the catch block.

    
    #include <iostream>
    using namespace std;
    
    class Test {
    public:
     Test() { cout << "Constructor of Test " << endl; }
     ~Test() { cout << "Destructor of Test " << endl; }
    };
    
    int main()
    {
     try {
      Test t1;
      throw 50;
     }
     catch (int i) {
      cout << "Caught " << i << endl;
     }
    }
    
     
    

    Output:

    
    Constructor of Test 
    Destructor of Test 
    Caught 50