If I call a destructor explicitly ( myObject.~Object() ) does this assure me that the object will be appropriately destroyed (calling all child destructors) ?
Ok so
Yes, a destructor, even when called explicitly, will destroy its subobjects properly.
As you seem to realize, it's a rare action to do, but perhaps as part of a well tested and documented library it may be useful. But document (and profile) it since even though it's valid and safe, every maintainer (including you) will never feel comfortable with it.
I would consider overriding new for the objects you want special allocation and deallocation behaviour for - after all that's what it's for. A hybrid scheme of normal new and explicitly calling destructors sounds like a recipe for future headaches. For starters, any memory leak detection strategy is going to get thrown way off.
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:
#include <iostream>
class A
{
public:
A(){};
~A()
{
std::cout << "OMG" << std::endl;
}
};
int main()
{
A* a = new A;
a->~A();
delete a;
return 0;
}
output:
OMG
OMG
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).
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.
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:
http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.9