Calling destructors in C++ explicitly

Started by
16 comments, last by level10boy 22 years, 3 months ago
OK, maybe I''m being really thick here, but why did the above program (3rd reply) print out ''I''m dying!'' twice? It appears that the foo method''s call to ~Test() executed the code in the destructor but could not destroy the object (as I would have expected as is was still within one of the objects methods). Then, when the program terminated the destructor was called again and destroyed t. Is this correct? (And if so, would calling the destructor by f->~Test() from the main method actually delete f?)

Thanks

Enigma
------
...given me solely for my own...
Advertisement
Thanks for all your replies, they were very useful.
It was executed twice as the object went out of scope and it wasn''t dynamically allocated. Basically what has happened is like allocating the object dynamically and then calling the destructor and then deleting the object :

#include

using namespace std;
class Test{
public:
void foo () { this->~Test (); }
~Test () { cout << "I''m dying!\n"; }
};

int main ()
{
Test* t = new Test();
t->foo (); // i''m dying
delete t; // i''m dying
return 0;
}

Same effect....

If it isn't working, take a bath, have a think and try again...

Calling the destructor does not destroy the object. But destroying the object (ie with delete) calls the destructor.

So I think the answer to level10boy''s question is yes. It is like calling a normal function I guess.
Ok guys (for everyone except stoffel who already knows) ... here''s c++ allocation / deletion, construction / destruction 101.

Memory Allocation and Deletion is NOT inheirantly tied to object allocation and deallocation in C++.

When you declare and object on the stack (a local variable) OR allocate an object using the new operator. The compiler is doing TWO things ... allocating space for your object, and THEN calling the constructor and passing it the address of the object (as this). When a local object goes out of scope, or you call the delete operator, the compiler is also doing two things ... calling the destructor and THEN reclaiming the memory used by the object. C++ allows you to seperate these steps if you want ... like the following example.

Step 1. call malloc to allocate space for an object - this allocates the memory.
Step 2. call the placement new operator and pass in the allocated address - this initializes the object.
Step 3. use the object.
Step 4. call the destructor for the object - this performs UNINITIALIZATION ... but does NOT reclaim any memory ... it JUST runs the code in the destructor.
Step 5. call the placement new operator again (to put ANOTHER object in the same memory (since it is no longer in use)
Step 6. use the second object.
Step 7. call the destructor to uninitialize the second object.
Step 8. call free to return the memory to the heap.

Tada ... a perfect example of the sepearation between the two concepts (i hope) ... now WHY would you want to do this???

Heres a few possibilities:
A. You have to use a certain special address (perhaps the fixed location of the video buffer in your graphics driver) - but want to be able to access it as an object, with all the corresponding type checking and syntax.
B. You are writing a special purpose memory manager, or using one, so you must have the ability to locate your objects where the memory manager wants them.
C. Your class objects will be managed by some C code, which means they must have been allocated with malloc ... cause the codes gonna free them with free() ... NOTE - this only really makes sense when you don''t require the destructor to be called for correct maintenece.
D. You are writing containers (ala STL) which preallocate memory in chunks, and then put objects their as needed.

Hope this helps
Another way you can do this is to add a Destroy function to the class...

  class Foo{    Foo() { cout << "Foo Constructor" << endl; }    ~Foo() { cout << "Foo Destructor" << endl; }    void Destroy()    {        delete this;    }}  


But, I''m not sure how pure this is

Dave "Dak Lozar" Loeser
Dave Dak Lozar Loeser
"Software Engineering is a race between the programmers, trying to make bigger and better fool-proof software, and the universe trying to make bigger fools. So far the Universe in winning."--anonymous
In simplest terms - the constructor and deconstructor are normal funcions, but the compiler knows to automatically call the respective function whenever it allocates/frees the memory (at the right time of course).
^ that would make them special functions
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara

This topic is closed to new replies.

Advertisement