Destructor case:
Exception in destructor are dangerous. Firstly the exception here may cause the abnormal termination of C++ program. This can happen when object may go out of its scope. However, if the program has written sufficient catch blocks and it manages to survive, then also it is problematic. Basically, this may still cause memory leaks or resource leaks and potentially may cause undefined behavior.
Memory Leak Example
#include <iostream> //main header
using namespace std; //namespace
class MainFunda
{
int iindex;
public:
MainFunda(int ix) : iindex(ix)
{
cout << "MainFunda() constructor : "
<< iindex
<< endl;
}
~MainFunda()
{
if(iindex >= 4) throw;
//Throwing exception
cout << "~MainFunda() Destructor : "
<< iindex
<< endl;
}
};
int main()
{
std::vector<MainFunda> av;
av.reserve(5);
for (int ik=1; ik<=5; ik++)
{
MainFunda* tmp = new MainFunda(ik);
av.push_back(*tmp);
}
cout << "vector going out-of-scope"
<< endl;
return 0;
}
In above program, construction happens for 5 objects, but destruction happen for only 3 objects. The fourth and fifth object do not get destroyed. This is because, exception ultimately is happening in destructor of vector. Therefore, after the exception, rest of the destruction is skipped.
Output:
Exception Handling in destructor:
Any task that may cause exception should not be performed without proper exception handling. The exception handler should either gracefully terminate the program or swallow the exception. In no case, the program should allow an exception to leave destructor.
The following example now has added proper try-catch block in same program. This shall catch the exception during destruction of fourth and fifth object.
#include <iostream> //main header
#include <vector> //for stl vector
using namespace std; //namespace
class MainFunda
{
int iindex;
public:
MainFunda(int ix) : iindex(ix)
{
cout << "MainFunda() constructor : "
<< iindex
<< endl;
}
~MainFunda()
{
try
{
if(iindex >= 4) throw iindex;
cout << "~MainFunda() Destructor : "
<< iindex
<< endl;
}
catch(int ii)
{
cout << "Failed Destructor : "
<< ii
<< endl;
}
}
};
int main()
{
std::vector<MainFunda> av;
av.reserve(5);
for (int i=1; i<=5; i++)
{
MainFunda* tmp = new MainFunda(i);
av.push_back(*tmp);
}
cout << "vector going out-of-scope"
<< endl;
return 0;
}
The destructor of class MainFunda has handled the exception. Therefore, the destruction of vector shall complete now. The output clearly shows that all the objects are getting destroyed.