When are destructors called? Need help

I am having trouble undertsanding when destructors are called. As I try to analyse the output of the code below, when i=0, the destructor is called after the exception has been caught, but when i=1 or i=2, "object" is destructed during the process.

Someone has said that destructed are usually called when it goes out of scope, i.e { }, I don't understand what he means. Help..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  #include <iostream>
using namespace std;
class Class {
public:
	string msg;
	Class(string txt):msg(txt){cout<<"Object [" << msg << "] constructed" << endl; }
	~Class(void) { cout << "Object [" << msg << "] destructed" << endl; }
	void Hello(void) { cout << "Object [" << msg << "] says: hello" << endl; }
};
void DoCalculations(int i) {
	if(i == 0) 
		throw Class("exception 1");
	Class object("object");
	if(i == 1)
		throw Class("exception 2");
	object.Hello();
	if(i == 2)
		throw Class("exception 3");
}
int main(void) {
    for(int i = 0; i < 3; i++) {
	try {
	   cout << "-------" << endl;
	   DoCalculations(i);
	} catch (Class &exc) {
	   cout << "Caught!" << endl;
	   cout << exc.msg << endl;
	}
    }	
    return 0;
}
Last edited on
Yeah, constructors are implicitly called when an object goes out of scope. At least, this is certain true in the case of objects created on the stack.

If you create an object using the new operator, then the destructor will run when you use the delete operator on that object. You need to be careful in this instance as you could wind up with memory leaks or dangling pointers. Most people seem to be leaning towards some sort of smart pointer now (C++ 11 and, I believe, Boost both make use of these).

Hopefully this code might clear things up a little:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <string>

struct Foo
{
    static unsigned int count;
    std::string name;
    Foo( std::string name ): name( name )
    { 
        count++;
        std::cout << "C'tor for " << name << ". There are " << count << " foo instances\n";
    }
    ~Foo()
    {
        count--;
        std::cout << "D'tor for " << name << ". There are " << count << " foo instances left\n";
    }
};

unsigned int Foo::count = 0;

int main( int argc, char* argv[] )
{
    Foo a( "a" ); // Stack foo created, alive until scope of main ends
    Foo *b = new Foo( "b" ); // Heap foo created, alive until we delete it

    // Let's create a stack object inside a scope
    {
        Foo c( "c" ); // Stack foo created, alive until this scope ends
    } // c will die here

    delete b; // b will die here

} // a will die here 


Hope this helps. :-)
Last edited on
"object" gets gets constructed when the program flow reaches it. If i==0 then you throw an exception and object doesn't get constructed or destroyed.

Your "exception n" instances are actually a subtle case. When you throw Class, it creates a temporary object. The compiler destroys these when the last reference to them goes out of scope. Since it's being thrown and caught by reference, it doesn't get destroyed until control flows out of the catch block in your main program.

Here is the output of the program with some comments

-------
Object [exception 1] constructed    // "object" doesn't get constructed
Caught!
exception 1
Object [exception 1] destructed     // destroyed when you leave the catch block
-------
Object [object] constructed            // because control flowed to line 13
Object [exception 2] constructed
Object [object] destructed             // because you're leaving DoCalculations
Caught!
exception 2
Object [exception 2] destructed    // because you're leaving the catch block
-------
Object [object] constructed           // line 13 again
Object [object] says: hello            // line 16
Object [exception 3] constructed
Object [object] destructed            // leaving DoCalculations
Caught!
exception 3
Object [exception 3] destructed   // leaving the catch block


Topic archived. No new replies allowed.