Function-level try-catch
In C++, the functions have their own try-catch blocks. The behavior is similar to regular try-catch which are present in any scope but also at function-level. There will be try block at the function declaration and then a function specific catch-block to catch any exception coming out of the function.
A function-level can have not just one but it can have a sequence of catch blocks. The scope of catch block is connected with the entire body of the function. Constructor function also uses function-level try-catch. In such case, it associates also the member initializer list (if any) as well. This means, this try-catch can trap exception even from initializer list.
Constructor catch block catches any exception from constructor. Example, when any statement in c++ constructor body throws exception. Exactly, similar behavior happens, whenever any member object constructor or parent class constructor throws exception. The catch block catches all these exceptions. Same behavior is present in case of destructor also.
#include <iostream> //main header
using namespace std;//for namespace
void myfunc() try //Function-level try
{
cout << "Started Function-level try-catch" << endl;
throw 5;
}
catch(int i) //Function-level catch
{
cout << "Caught in Function-level try-catch : " << i << endl;
}
int main() //main function
{
cout << "Starting Main()" << endl;
myfunc();
cout << "Ending Main()" << endl;
return 0;
}
The output is:
Starting Main()
Started Function-level try-catch
Caught in Function-level try-catch : 5
Ending Main()
Exception thrown from the constructor or destructor
Every catch block in the function-try-block for a constructor terminates the program by throwing an exception. Therefore, if the control reaches the end of such handler, the current exception is automatically rethrown as if by throw. Same behavior is with the destructor.
#include <iostream> //main header
using namespace std; //for namespace
class MainFunda
{
public:
MainFunda() try
{
cout << "MainFunda::MainFunda()" << endl;
throw 4;
}
catch(int p) //Constructor Handles
{
cout << "Constructor catch block" << endl;
}
};
int main()
{
try
{
MainFunda a; //Constructor throws
}
catch (...) //Main handles
{
cout << "Catch - main function" << endl;
}
return 0;
}
The output is
Clearly, even though constructor has function level try-catch, but without try-catch in main function, the program shall terminate.
Return value from constructor catch block
When constructor throws an exception and constructor-level catch block traps this exception. In such case, the constructors catch block should not return any value. The compiler shall signal an error for any such attempt. In all other cases, the such catch blocks can return any value. The following example code demonstrates this behavior.
#include <iostream> //main header
using namespace std; //for namespace
class MainFunda
{
public:
MainFunda() try
{
cout << "MainFunda::MainFunda()" << endl;
throw 4;
}
catch(int p)
{
cout << "Constructor catch block" << endl;
return 8; //Return value from constructor catch
}
};
int main()
{
MainFunda a;
return 0;
}
The output will be an error:
To resolve the above error, the catch block must comment or remove the return statement
catch(int p)
{
cout << "Constructor catch block" << endl;
//return 8; Commented return
}