C++ - Exceptions and Stack Unwinding Process
Exceptions (try, throw, catch) are very useful in C++. With in the catch block, we can either write the log message or let the user knows about what went wrong. Sometimes it can be used to come out of the nested for loops for 3 to 4 levels.
When throwing an exception with in a try block, program control then directly goes to the corresponding catch block or default catch(...) by doing the stack unwinding.
Stack unwinding is the very good feature in C++. During this process all the destructors are called in the reverss order.
Source Code
#include <iostream>
class CConfig
{
std::string m_name;
public:
CConfig()
{
m_name = "";
}
CConfig(const char *name)
{
this->m_name = name;
}
CConfig(const CConfig &other)
{
this->m_name = other.m_name;
}
const CConfig& operator = (const CConfig &other)
{
this->m_name = other.m_name;
return *this;
}
void CalculateError()
{
std::cout << "Exception Occurs\n";
throw -1; // just throw an exception
}
};
class MyObjectONE
{
public:
MyObjectONE() { }
~MyObjectONE()
{
std::cout << "Calling destructor of MyObejectOne\n";
}
};
class MyObjectTWO
{
public:
MyObjectTWO() { }
~MyObjectTWO()
{
std::cout << "Calling destructor of MyObjectTWO\n";
}
};
class MyObjectTHREE
{
public:
MyObjectTHREE() { }
~MyObjectTHREE()
{
std::cout << "Calling destructor of MyObjectTHREE\n";
}
};
void TestException(CConfig &config)
{
config.CalculateError(); // Throws an exception
}
void TestFunc()
{
std::cout << "TestFunc Begins\n";
CConfig theConfig("MyApp");
MyObjectONE one;
MyObjectTWO two;
MyObjectTHREE three;
TestException(theConfig);
// The remaining lines will not get executed because of throwing exception in TextException
std::cout << "TestFunc Ends\n";
}
int main()
{
try
{
for(int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
for(int k = 0; k < 10; k++)
{
TestFunc();
}
}
}
}
catch(...)
{
}
return 0;
}
Output
TestFunc Begins
Exception Occurs
Calling destructor of MyObjectTHREE
Calling destructor of MyObjectTWO
Calling destructor of MyObejectOne
|