Consider the following code:
#include <iostream>
using namespace std;
class Test {
static int count;
int id;
public:
Test() {
count++;
id = count;
cout << "Constructing object number " << id << endl;
if(id == 4)
throw 4;
}
~Test() { cout << "Destructing object number " << id << endl; }
};
int Test::count = 0;
int main() {
try {
Test array[5];
} catch(int i) {
cout << "Caught " << i << endl;
}
}
The code above produces the following output:
Constructing object number 1
Constructing object number 2
Constructing object number 3
Constructing object number 4
Destructing object number 3
Destructing object number 2
Destructing object number 1
Caught 4
I thought destructors were always called when objects become out of scope, even when exceptions are thrown. Why isn’t one of the Test instances’ destructors called in this case?
You are creating an array of
5Testobjects but you throw an exception after you create3complete objects, The exception is thrown while in the constructor of the4th object. The construction of the4th object is not complete until the closing brace of the constructor is reached.The stack unwinds calling destructor for those
3completely constructed objects in the opposite order in which they were created, since the4th and5th object were never constructed the destructor for them is never called.The rule for exception is:
Once an exception is thrown destructors for all completely created objects within that scope will be called.
An completely created object is one whose constructor has been called cleanly without any exceptions.