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..
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:
#include <iostream>
#include <string>
struct Foo
{
staticunsignedint 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";
}
};
unsignedint 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
"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