views:

257

answers:

6

How does C++ ensure that destructors are called for stack assigned objects? What happens to the destructor function (or a pointer to it) when I assign dynamic memory as follows:

class MyClass {
public:

  ~MyClass()
  {
    std::cout<<"Destructor called."<<std::endl;
  }  

  MyClass()
  {
    std::cout<<"Constructor called."<<std::endl;
  }

};

....................................................................

//Limit scope for example
{
  MyClass instance;
}

The constructor and destructor are both called. What's going on here?

+1  A: 

The constructor is called because you're creating an object. The destructor is called because your cleaning up that object. Remember, in C++, objects declared on the stack are automatically cleaned up when their containing scope goes away.

dicroce
+2  A: 

The constructor is called as soon as the variable is created. As for the destructor, the compiler emits code at the end of scope to call the destructor. To get a feel for this, try using a 'goto', or switch/case construct to prematurely exit the scope, and watch the compiler complain.

Managu
"The constructor is called as soon as the variable is created." Well, object creation happens when the constructor is called, so this is no wonder. The memory for the variable, OTOH, might be provided earlier.
sbi
You can exit the scope with goto, as far as I know, and the compiler will still know that the object goes out of scope. What you are not allowed to do is to step over object declarations (construction) with goto/switch.
UncleBens
@UncleBens: Make this "object definitions", but otherwise you're right. (I read to fast and hadn't even seen this error in Managu's answer.)
sbi
What I was curious about is how the constructor and destructor are implemented. One should be able to produce behaviour analogous to a destructor call for stack assigned variables in C (admittedly with some difficulty) but I can't see how.
j coe
+6  A: 

The compiler inserts a call to the destructor for the object at an appropriate position.

ur
+3  A: 

Yes, both the constructor and destructor are called. And even more important:

{
 MyClass instance;
 throw "exception";
}

in this example, the destructor is also called. That is why I always prefer to allocate my objects on stack (or at least wrap the dynamic allocations with a stack-allocated guardians).

SadSido
+3  A: 

You wouldn't wonder why this

{
  int i;
}

creates and destroys i automatically, would you? C++ does a lot to allow you to create types that behave just like built-in types. And just like with built-in types, in C++ (other than in, say, Java or C#), this

{
  MyClass instance;
}

doesn't just define a reference that might be bound to null or some actual object. It creates an actual object.

Object creation comes in two steps: First (upon entering the scope) the raw memory is provided. Then (when the object definition is encountered) the constructor is called. For built-in types no constructor is called. If you don't initialize a built-in variable, it has a random value. (Actually it's whatever the bit pattern was at the memory provided in step #1.) Object deletion, too, comes in two steps: First, the destructor is called (again, not for built-ins), then the memory is returned to the run-time system.

(Note that providing and deleting memory for stack variables usually is as cheap as incementing/decrementing a register.)

sbi
A: 

well it did not call the destructor just after constructor.

it calls it when it about to terminate the programme.

int main() { MyClass obj;

cout<<"testing....1"<<endl;

cout<<"testing....2"<<endl;
return 0;

}

ans: Constructor called. testing....1 testing....2 Destructor called.

biswajit
It does not call the destructor when the program is about to terminate. The destructor is called when the stack object goes out of scope. Because you are doing this in main, those two happen to coincide.
R Samuel Klatchko