Utkarsh Srivastav
Utkarsh Srivastav

Reputation: 3227

Destructor not called when an exception is thrown

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?

Upvotes: 6

Views: 984

Answers (2)

Invictus
Invictus

Reputation: 4338

Instead of writting the cout statement after id=count as mentioned below:-

    id = count;
    cout << "Constructing object number " << id << endl;
    if(id == 4)
    throw 4;

you should have written it after the throw statement . That would have given you a better picture of what happened . Like this :-

Test() {
count++;
id = count;
if(id == 4)
   throw 4;
 cout << "Constructing object number " << id << endl;
     }

The o/p would have been :- Constructing object number 1 Constructing object number 2 Constructing object number 3 Destructing object number 3 Destructing object number 2 Destructing object number 1 Caught 4

Upvotes: 3

Alok Save
Alok Save

Reputation: 206636

You are creating an array of 5 Test objects but you throw an exception after you create 3 complete objects, The exception is thrown while in the constructor of the 4th object. The construction of the 4th object is not complete until the closing brace of the constructor is reached.

The stack unwinds calling destructor for those 3 completely constructed objects in the opposite order in which they were created, since the 4th and 5th 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.

Upvotes: 8

Related Questions