Exception Handling in C++
Exception Handling in C++ Interview with follow-up questions
Interview Question Index
- Question 1: What is exception handling in C++ and why is it important?
- Follow up 1 : Can you explain the difference between error and exception?
- Follow up 2 : What are the key components of exception handling in C++?
- Follow up 3 : How does exception handling improve the robustness of a program?
- Question 2: Can you explain the try-catch block in C++ with an example?
- Follow up 1 : Can there be multiple catch blocks for a single try block?
- Follow up 2 : What happens if an exception is not caught?
- Follow up 3 : How does the catch block determine which exception to catch?
- Question 3: What is the use of the throw keyword in C++?
- Follow up 1 : Can you throw exceptions of any data type?
- Follow up 2 : What happens after an exception is thrown?
- Follow up 3 : Can you provide an example of using throw in a program?
- Question 4: What is the purpose of the standard exception library in C++?
- Follow up 1 : Can you name a few commonly used classes in the standard exception library?
- Follow up 2 : How can we create our own exception classes?
- Follow up 3 : What is the hierarchy of standard exception classes in C++?
- Question 5: What is the concept of exception propagation in C++?
- Follow up 1 : Can you explain with an example how exception propagation works?
- Follow up 2 : What happens if an exception is not caught in the current function?
- Follow up 3 : Can an exception be caught in another function other than the one it was thrown in?
Question 1: What is exception handling in C++ and why is it important?
Answer:
Exception handling in C++ is a mechanism that allows the programmer to handle errors or exceptional situations that may occur during the execution of a program. It provides a way to gracefully handle these errors and prevent the program from crashing. Exception handling is important because it helps in writing robust and reliable code by separating the error-handling code from the normal code flow. This makes the code more readable, maintainable, and less prone to bugs.
Follow up 1: Can you explain the difference between error and exception?
Answer:
In C++, an error is a problem that occurs during the execution of a program and prevents it from continuing. Errors can be categorized into compile-time errors and runtime errors. Compile-time errors are detected by the compiler and prevent the program from being compiled. Runtime errors occur during the execution of the program and can cause it to terminate abruptly.
On the other hand, an exception is an event that occurs during the execution of a program that disrupts the normal flow of instructions. Exceptions are typically caused by exceptional conditions or errors that can be handled by the program. Unlike errors, exceptions can be caught and handled by the program, allowing it to continue its execution.
Follow up 2: What are the key components of exception handling in C++?
Answer:
The key components of exception handling in C++ are:
Try block: It is used to enclose the code that may throw an exception. If an exception is thrown within the try block, it is caught and handled by the corresponding catch block.
Throw statement: It is used to explicitly throw an exception. It can be used to throw built-in types, user-defined types, or even objects of standard library classes.
Catch block: It is used to catch and handle exceptions thrown by the try block. Multiple catch blocks can be used to handle different types of exceptions.
Exception object: When an exception is thrown, an object containing information about the exception is created. This object can be accessed and used within the catch block to handle the exception.
Standard exception classes: C++ provides a set of standard exception classes that can be used to handle common types of exceptions. These classes are defined in the header.
Follow up 3: How does exception handling improve the robustness of a program?
Answer:
Exception handling improves the robustness of a program in several ways:
Prevents program crashes: Exception handling allows the program to gracefully handle errors and exceptional situations. Instead of crashing, the program can catch and handle the exception, preventing the program from terminating abruptly.
Separates error-handling code: Exception handling separates the error-handling code from the normal code flow. This makes the code more readable and maintainable. It also reduces the chances of bugs and makes it easier to debug and fix issues.
Provides a centralized error-handling mechanism: Exception handling provides a centralized mechanism to handle errors. Instead of scattering error-handling code throughout the program, exceptions can be caught and handled in a single location, making it easier to manage and maintain.
Supports graceful recovery: Exception handling allows the program to recover from errors and continue its execution. By catching and handling exceptions, the program can take appropriate actions to recover from the error and continue its normal flow of execution.
Question 2: Can you explain the try-catch block in C++ with an example?
Answer:
In C++, the try-catch block is used for exception handling. It allows you to catch and handle exceptions that occur during the execution of a program. The try block contains the code that may throw an exception, while the catch block is used to handle the exception if it occurs.
Here's an example:
try {
// Code that may throw an exception
int result = divide(10, 0);
cout << "Result: " << result << endl;
}
catch (const std::exception& e) {
// Exception handling code
cout << "Exception caught: " << e.what() << endl;
}
In this example, the divide
function is called inside the try block. If an exception is thrown, it will be caught by the catch block. The catch block takes a parameter of type const std::exception&
, which allows you to access information about the exception. You can then handle the exception accordingly.
Follow up 1: Can there be multiple catch blocks for a single try block?
Answer:
Yes, there can be multiple catch blocks for a single try block. Each catch block can handle a different type of exception. The catch blocks are evaluated in the order they appear, and the first catch block that matches the type of the thrown exception will be executed. If no catch block matches the type of the thrown exception, the exception will propagate to the next level of the call stack.
Follow up 2: What happens if an exception is not caught?
Answer:
If an exception is not caught, it will result in program termination. When an exception is thrown and not caught by any catch block, the program will terminate and an error message will be displayed. This is known as an unhandled exception.
Follow up 3: How does the catch block determine which exception to catch?
Answer:
The catch block determines which exception to catch based on the type of the thrown exception. When an exception is thrown, the catch blocks are evaluated in the order they appear. The first catch block that matches the type of the thrown exception will be executed. If no catch block matches the type of the thrown exception, the exception will propagate to the next level of the call stack.
For example:
try {
// Code that may throw an exception
throw MyException();
}
catch (const std::exception& e) {
// Catch block for std::exception and its derived classes
cout << "Caught std::exception: " << e.what() << endl;
}
catch (const MyException& e) {
// Catch block for MyException
cout << "Caught MyException" << endl;
}
In this example, if a MyException
object is thrown, it will be caught by the second catch block. If a std::exception
object or any of its derived classes are thrown, they will be caught by the first catch block.
Question 3: What is the use of the throw keyword in C++?
Answer:
The throw keyword in C++ is used to explicitly throw an exception. When an exception is thrown, the program flow is interrupted and the control is transferred to the nearest catch block that can handle the exception.
Follow up 1: Can you throw exceptions of any data type?
Answer:
Yes, in C++, you can throw exceptions of any data type. The thrown exception can be of a built-in data type, a user-defined data type, or even a pointer or reference type.
Follow up 2: What happens after an exception is thrown?
Answer:
After an exception is thrown, the program flow is interrupted and the control is transferred to the nearest catch block that can handle the exception. If there is no catch block that can handle the exception, the program terminates and an error message is displayed.
Follow up 3: Can you provide an example of using throw in a program?
Answer:
Sure! Here's an example of using throw in a program:
#include
int divide(int a, int b) {
if (b == 0) {
throw "Division by zero exception";
}
return a / b;
}
int main() {
try {
int result = divide(10, 0);
std::cout << "Result: " << result << std::endl;
}
catch (const char* exception) {
std::cout << "Exception caught: " << exception << std::endl;
}
return 0;
}
In this example, the divide
function throws an exception with the message "Division by zero exception" if the second argument is zero. The exception is then caught in the main
function using a catch block that handles exceptions of type const char*
.
Question 4: What is the purpose of the standard exception library in C++?
Answer:
The purpose of the standard exception library in C++ is to provide a set of predefined exception classes that can be used to handle various types of runtime errors and exceptional conditions in a program. These exception classes are designed to be thrown and caught by the program to handle exceptional situations.
Follow up 1: Can you name a few commonly used classes in the standard exception library?
Answer:
Yes, here are a few commonly used classes in the standard exception library:
std::exception
: The base class for all standard exceptions. It provides a virtual member functionwhat()
that returns a C-style string describing the exception.std::runtime_error
: Represents errors that can occur during runtime, such as logical errors or resource exhaustion.std::logic_error
: Represents errors that are caused by incorrect programming logic, such as invalid arguments or incorrect use of functions.std::out_of_range
: Represents errors that occur when accessing elements out of the valid range, such as array index out of bounds or iterator out of range.std::bad_alloc
: Represents errors that occur when memory allocation fails.
Follow up 2: How can we create our own exception classes?
Answer:
To create our own exception classes in C++, we can derive them from the base class std::exception
or any of its derived classes. Here is an example of creating a custom exception class:
#include
class MyException : public std::exception {
public:
const char* what() const noexcept override {
return "My custom exception";
}
};
In this example, MyException
is derived from std::exception
and overrides the what()
function to provide a custom error message. We can then throw and catch instances of MyException
in our program.
Follow up 3: What is the hierarchy of standard exception classes in C++?
Answer:
In C++, the standard exception classes form a hierarchy with std::exception
as the base class. Here is a simplified hierarchy of some commonly used standard exception classes:
std::exception
├── std::runtime_error
│ ├── std::logic_error
│ │ ├── std::invalid_argument
│ │ ├── std::domain_error
│ │ ├── std::length_error
│ │ └── ...
│ └── std::out_of_range
└── std::bad_alloc
This hierarchy allows for catching exceptions at different levels of specificity. For example, catching std::exception
will catch all standard exceptions, while catching std::runtime_error
will catch exceptions related to runtime errors.
Question 5: What is the concept of exception propagation in C++?
Answer:
Exception propagation is the process by which an exception is passed from one function to another until it is caught and handled. When an exception is thrown in a function, the function's execution is immediately stopped and the exception is propagated to the calling function. This continues until the exception is caught and handled or until it reaches the top-level function, in which case the program terminates.
Follow up 1: Can you explain with an example how exception propagation works?
Answer:
Sure! Here's an example:
#include
void functionB()
{
throw std::runtime_error("Exception in function B");
}
void functionA()
{
functionB();
}
int main()
{
try
{
functionA();
}
catch(const std::exception& e)
{
std::cout << "Caught exception: " << e.what() << std::endl;
}
return 0;
}
In this example, when functionB()
throws an exception, it is propagated to functionA()
, and then to main()
. Finally, the exception is caught in the catch
block in main()
and the error message is printed.
Follow up 2: What happens if an exception is not caught in the current function?
Answer:
If an exception is not caught in the current function, it will be propagated to the calling function. This process continues until the exception is caught and handled or until it reaches the top-level function. If the exception reaches the top-level function without being caught, the program terminates and an error message is displayed.
Follow up 3: Can an exception be caught in another function other than the one it was thrown in?
Answer:
Yes, an exception can be caught in another function other than the one it was thrown in. When an exception is thrown, the program searches for a matching catch
block in the current function. If a matching catch
block is not found, the exception is propagated to the calling function. This process continues until a matching catch
block is found or until the exception reaches the top-level function. So, it is possible to catch an exception in a function that is higher up in the call stack than the function where the exception was thrown.