Does the destructor deallocate memory assigned to the object which it belongs to or is it just called so that it can perform some last minute housekeeping before the object is deallocated by the compiler?
The destructor is called to allow the object to perform cleanup as well as to destroy any other objects the object itself has created.
The OS will deal with deallocating the object itself after finishing the destructor.
The 'compiler' doesn't delete anything. It creates code that does things at runtime.
When you write delete somePointer;
the compiler, in essence, writes:
if ( has_virtual_destructor( * somePointer ) ) {
// virtual dispatch to a compiler-generated function
dynamic_cast< true_dynamic_type * >(somePointer)->destroy_dynamic_type();
/* contents of true_dynamic_type::destroy_dynamic_type() {
this->~true_dynamic_type();
operator delete( this); // executed within class context
} */
} else {
somePointer->~ClassName();
operator delete(somePointer);
}
In other words, the destructor gets called, and then operator delete gets called to free the storage.
If the destructor is virtual, a virtual dispatch is used to perform the entire operation on the object in its most-derived form. A common way of implementing this is to add hidden arguments to every virtual destructor.
1) destructor doesn't belong to object, it belongs to class
2) It calls destructor for all the user defined types (class objects) within its class.
3) Cleanup is optional activity which is done only if it is really required
The memory is deallocated right after the destructor function exits and before execution returns to the "delete" call or point where an object instance goes out of scope. In theory it is possible to set up a different memory manager to handle new and delete, but that would be an explicit change of the default behavior.
More specifically, nobody but the programmer deallocates memory in C++. If the object is on the stack, it is resident in the memory space of the program, and takes space during the lifetime of the program. If it is on the heap, whoever created the object is responsible for deallocating it. Thats what delete
does. This brings us to the destructor - if you create objects in your class, the destructor allows you to delete them as the class leaves scope. It lets you "turn out the lights as you leave".
Destructors automatically call the destructors on member variables of the object being destroyed. Those destructors may or may not free up memory. However, a pointer has no destructor, or if you prefer, a pointer's destructor does nothing. It does not free the memory that it points to. If an object contains a pointer to an object obtained from "new" or "malloc," it is up to the programmer of that object to make the destructor do the right thing. You should program your destructor to "delete" or "free" the memory if it is conceptually part of the object being destructed. For example, a "vector" object typically obtains memory from the heap, because the amount of memory required is not generally known at compile time. That memory is conceptually part of the vector object, and thus the programmer of the vector class must call "delete" on it in the destructor. Standard Template Library classes like std::vector do it properly.
On the other hand, some objects contain references to other objects. A dictionary or index will contain references (pointers) to objects that are not conceptually part of them. That memory must not be freed by the destructor. (If you remove your phone number from the phone book, you do not want your phone to automatically disappear.)
There are exceptions that the novice need not be concerned with at first. One is when the object and its containers are programmed to use reference-counting, and the referenced object is not really freed until the last object referring to it lets it go. Another exception is in the case of "placement new."