If I call a destructor explicitly ( myObject.~Object() ) does this assure me that the object will be appropriately destroyed (calling all child destructors) ?
Ok some code:
class Object
{
virtual ~Object()
{}
};
class Widget : public Object
{
virtual ~Widget()
{}
};
...
Object* aWidget = new Widget(); //allocate and construct
aWidget->~Object(); //destroy and DON'T deallocate
I know I could just delete the object, but I don't want to. I want to keep the allocated memory handy as an important optimization.
Thanks!
Calling the destructor is fine. However, beware of the type you're calling it on. If that type doesn't have (didn't inherit) a virtual destructor, you might get unexpected behaviour.
Also, as mentioned, the destructor does not free any memory, but I guess that's the reason you want to call it manually in the first place.
Plus, unless I'm mistaken, calling the destructor manually is the only option you have if you used placement new to call the constructor.
The answer is... nearly always.
If your object has a non-virtual destructor, and is then sub-classed to add child elements that need freeing... then calling the destructor on the object base class will not free the child elements. This is why you should always declare destructors virtual.
We had an interesting case where two shared libraries referenced an object. We changed the definition to add child objects which needed freeing. We recompiled the first shared library which contained the object definition.
HOWEVER, the second shared library was not recompiled. This means that it did not know of the newly added virtual object definition. Delete's invoked from the second shared library simply called free, and did not invoke the virtual destructor chain. Result was a nasty memory leak.
Yes it will call all the child destructors so it will work as you are expecting.
The destructor is just a function after all, it just so happens that it gets called when objects are deleted.
Therefore if you use this approach be careful of this:
The destructor is called a second time when delete is actually called on the object, so if you delete pointers in your destructor, make sure that you set them to 0, so that the second the destructor is called nothing will happen (as deleting a null pointer does nothing).
Yes. But holy smokes, are you sure about this? If so I would use placement
new
to construct yourWidget
. Using placementnew
and then explicitly calling the destructor is an acceptable, if unusual, idiom.Edit: Consider allocating the memory yourself manually rather than using
new
to allocate the first object and then re-using its memory afterward. That allows you complete control over the memory; you could allocate big chunks at a time, for instance, rather than allocating a separate block of memory for eachWidget
. That'd be fair savings if memory really is such a scarce resource.Also, and perhaps more importantly, you'd then be doing placement
new
"normally", rather than this hybrid regularnew
/placementnew
solution. I'm not saying it won't work, I'm just saying it's a rather, ah, creative solution to your memory problem.Running the destructor does not free memory used by the object being destructed - the delete operator does that. Note, however, that the destructor may delete "child objects" and their memory will be freed as per usual.
You need to read up on placement new/delete as this allows you to control memory allocation and when constructors/destructors run.
See here for a little info:
STL containers do this. In fact, an STL allocator must provide a destroy method that calls an object's destructor (allcators also provide a deallocate method to deallocate the memory that used to hold an object). However, the advice from Stroustrup (The C++ Programming Language 10.4.11) is