What is The Rule of Three? mentions
After executing the body of the destructor and destroying any automatic objects
allocated within the body, a destructor for class X calls the destructors for
X's direct [...] members [n3126.pdf 12.4 §6]
Which leaves me wondering, what's the use of a destructor if not to destroy the members? Please provide examples
It is for additional cleanup that the members themselves are not responsible for. Or in the case of resource management to make sure the resources associated with he object are correctly released. Remember not all members have destructors that will be called (pointers don't have destructors). So if you have pointers you need to manually manage them.
Example resource management with pointers.
shared_ptr::~shared_ptr()
{
if (decrementReferenceCountAndCheckForZero())
{
cleanupResources();
}
}
Example. Working with frameworks. None of the members know about the framework but the worker does.
MyWorker::MyWorker()
{
Framwork::Register(this);
}
MyWorker::~MyWorker()
{
Framework::Unrigester(this);
}
Anything associated to the class instance that needs disassociation/release/special handling once the object ceases to exist.
Few examples:
File handles opened, owned and used by the instance and wont be used post object destruction.
Socktes, mutex etc opened and owned by the class instance.
All that statement means is if you have a destructor defined as
Foo::~Foo()
{
Bar b;
b.do_whatever();
}
then the b object's destructor is run before the destructors of any of Foo's members. The body of the destructor is executed, and the automatic object allocated within the body, i.e. b, is destroyed first.
Your class might manage resources that aren't released by calling the destructors of the data members of your object. If so, then the code to release the resource belongs in a destructor that you write.
For example if you allocate objects with new then they must be freed with delete. If you open a file with fopen then it's closed with fclose. If you take a Posix mutex with pthread_mutex_lock then it must be released with pthread_mutex_unlock.
For each kind of resource needs freeing you (or someone else) can write a class that manages and frees that resource, and provides access to its basic operations. Hence the existence of classes like std::unique_ptr, std::shared_ptr, std::lock_guard, std::fstream. Of course, for simplicity you usually want there to be only one class that manages a particular kind of resource. So, since std::lock_guard exists in C++11, the only reason that you'd write your own class to release a mutex would be if you're providing some alternative interface to the standard one. Classes with non-default destructors should ideally be rare in your own code -- often there already exist classes that you can use as data members or automatic variables, and whose destructors do the job.
This might help you
Suppose a class is having array of someClass which is dynamically created . In your constructor suppose you created
someClass * p = new someClass [10] ;
then in destructor you would write
delete []p ;
Related
In main function I create an object using new and don't delete it.I hope the heap space would be cleared once the process exits .The below is a sample code where object of class A is a member variable of class B. Class B also has a multimap as a member variable.
Class A
{
Public:
A(); //have definition in cpp file
~A();//have definition in cpp file
Private:
Int a;
};
Class B{
Private:
Std::multimap<string,string> map_test;
Public:
A a;
B(); //have definition inn cpp file
~B();//does not have any definition in cpp file
};
int main()
{
B *b = new B();
/* code section where it fills some 1000 key value pairs in the multimap
for some purpose */
return 0;
}
My understanding:
Even if i do not delete the object here, it won't create any issue as the heap space would be cleaned once the process exits.As my scope of the programme is limited as above and nobody else is going to reuse this.So is it good or bad not to use delete? What's your suggestion on this?
It should call the object's default destructor which then calls the implicit multimap destructor. So its not needed to explicitly clear the multimap.Please correct me if i am wrong.
In parent class it just declares the destructor and does not have any definition.So will it call implicit destructor or it will ignore calling it?(There is no reason of not defining it, just asking for better understanding. )
If it calls implicit destructor in case of parent class, should it call the child class destructor which is defined here?
As the parent class object is instantiated using new, it would be created in heap.Then where exactly the member variables of this parent object would be stored.For example object "a" is a member variable and by looking into the declaration of this member object, seems like it would be created in stack. I am just confused here how the parent object and its member child object exact memory creation happens. Can you please help me to understand this?
Yes, as long as your object is created in main.
However, if you ever want to alter this and for example create multiple instances of B, or use it inside another class, etc etc etc, that's a different story. Also, memory checking tools like valgrind are going to give you false positives on a new w/o delete which you will be tempted to ignore. But then, you may ignore a true memory leak if it becomes a habit.
Correct, now if it was a map<string, string*> then you would likely need to clean up
It will call default destructor
Yes it will
I guess, you are asking where base class member variables are stored ? They are also stored on the heap. They precede derived class fields in memory.
You have asked many question.
First its best practice to alwsys clear your memory even if the process exits and clears all the memory ( as it does) . Always handle it..its easy to do usining shared_ptr...
Destructors always get called in the right order however you multimap is a dangeorus as you should clear the elements in the multimap as ifyou store pointers it can cause a serious leak
Most OSs will clean up a process's heap space when the process exits. I wouldn't be surprised if there are a bunch of embedded OSs out there where that isn't the case, plus it is still bad practise as you do have a memory leak.
As you're leaking the memory, no destructors will be called. That said, if you're not implementing a destructor and rely on the compiler-generated default destructor, you should not declare it either - in fact I'm surprised that you're not getting a linker error. And yes, the default destructor for the multimap will delete the contents of the multimap as long as you observe the container's requirements for value semantics (ie, no raw pointers).
It is bad practise and as a programmer you should really make sure that you always manage your resources properly. Also, I don't see any reason for heap allocating b, you can just create the object on the stack and you won't have to think about resource management.
If you do declare it you'll have to provide an implementation as the declaration of the destructor will implicitly disable the compiler generated destructor. That's why I said above that I'm surprised you're not getting a link error.
The compiler will take care of the destruction of the base classes by walking the hierarchy and calling the destructors in reverse order of construction.
No, the whole object containing both A and B will be constructed on the heap - that's why you can alias a pointer to B as a pointer to A and interact with the derived class as if it was the base class.
Fact : there's no native (under the table) garbage collection in C++, though there are many things that can enforce some sort of garbage collection.
Thus, in your code, you have a memory leak. At the end of the scope in which you allocate a B, the memory you allocated _is not free'd.
Going through your list of questions :
No, if you don't delete the pointer, the memory won't be free'd. There are a few things that you can do regarding this topic :
Use the RAII idiom (Resource acquisition is initialization), i.e. use objects to manage memory :
Use smart pointers : these constructs enforce RAII (the most common in my opinion being std::shared_ptr and std::unique_ptr) and make sure the memory they are responsible for is correctly free'd.
It depends. If you allocated objects using the new operator, then inserted them in the map, but they aren't referenced anywhere else, then you should delete manually every entry of the map. It doesn't apply in this case because the map types aren't pointers.
The class could even omit a destructor declaration. If they are omitted, destructors (but also copy assignement operator, copy constructor and a default constructor) are generated by the compiler.
Edited: It depends, if you declared the member A a;, you don't have to explicitly delete it, its destructor will be called when the class that declares it as a member has its destructor called. but if it's a pointer that you allocated (e.g. in the constructor), then you have to delete it in the destructor.
Once you use dynamic memory allocation for an object, the whole object is on the heap, no matter how his members are declared.
I was wondering if default class destructors actually do anything when they're called.
I have been researching it and I've found that if I create a class with a function that calls its own destructor it doesn't do anything at all (i.e. all variables remain untouched and the instance still exists and is usable).
Does this mean that a class destructor can be thought of as an inherited virtual function that all classes have and a redefinition of it is possible (to delete pointers etc. and to clear member variables) but that if it's not redefined that it'll do nothing at all?
If so, couldn't a destructor essentially be used as a "clear all data" kind of function and make some parts of code more efficient by clearing a dynamically memory allocated variable and re-using it rather than getting the computer to find a new block of memory on the heap?
Thanks.
Default constructor calls the default constructor of all member variables, not including primitive types (char, int, pointers).
Destructor can be called explicitly, but it does not mean the dellocation of the object. If the object is on the stack, then it can not possibly do anything with it.
Destructors are not virtual by default, but they really should be if you plan to inherit from the class.
If the object is deallocated (goes out of scope, deleted from heap, or enclosing object is desctucted by any means) the desctuctor will be called.
I have been researching it and I've found that if I create a class with a function that calls its own destructor it doesn't do anything at all (i.e. all variables remain untouched and the instance still exists and is usable).
Consider this code:
#include <iostream>
struct A
{
~A()
{
std::cout << "A::~A" << std::endl;
}
};
struct B
{
A a;
};
int main()
{
B b;
std::cout << "Calling b.~B()" << std::endl;
b.~B();
std::cout << "Done" << std::endl;
}
You'll see that calling B's default destructor calls A's destructor, because B contains an A:
Calling b.~B()
A::~A
Done
A::~A
Only when b goes out of scope is the stack unwound and the synthesised B::~B() called and, in turn, A::~A() before their memory is free'd.
In addition to Notinlist's answer:
Default constructors call your base classes' constructors.
If so, couldn't a destructor essentially be used as a "clear all data"
kind of function and make some parts of code more efficient by
clearing a dynamically memory allocated variable and re-using it
rather than getting the computer to find a new block of memory on the
heap?
You're sort of describing a memory pool. If you want, your objects may acquire and return memory buffers to/from some pool system you invent. But for the most part allocations are fast enough and infrequent enough that it's not common (anymore) for people to do this. Not to say they are infrequent, but they need to be happening a lot to take notice of that performance hit.
Calling a destructor manually is generally a bad idea. The C++ FAQ section about destructors has plenty of good information about this.
If you do want to destroy an object explicitly you can use additional scopes to cause the destructor to be safely called (see this FAQ entry). This method also prevents you from using the object instance which has been destroyed. Although the instance may seem to be usable, it really is not.
If your intention is to free some, but not all, of the resources owned by an instance of a class you could try two things:
Define a clear() (or similar) method on the class.
Ensure that the invariant of the class is maintained after clear() is called.
Suppose that your initial approach to manually calling a destructor worked, or you chose to do something that like the clear() method above, in both cases you may run into problems later.
A well understood and often practiced method of resource management in C++ is Resource Acquisition Is Initialization (often abbreviated RAII, but ignore the name if it is confusing, the concept is understandable). See this Wikipedia article or this answer for useful information.
Here is the tl;dr though:
The lifetime of a resource should always be tied to the lifetime of
an object.
The lifetime of an object begins when the constructor completes
The lifetime of an object ends when the destructor completes.
Following this idiom will usually prevent C++ resource management problems before they occur.
Everywhere i read, if no destructor is defined the compiler creates one anyway. So what is the point of explicitly defining one?
Thank you
The compiler-provided default may not do everything you need done. For example, if you have dynamically allocated memory that needs to be deleted, you'll have to define the destructor yourself. The compiler will not do that for you.
In case you need to do something in the destructor.
For example, you might need to free memory or close a file handle.
The point of explicitly defining a C++ destructor is when the generated C++ one won't properly do the job of resource management. For example
class Example {
MyType* m_pValue;
Example() {
m_pValue = new MyType();
};
Sure C++ defines a destructor here but what does this destructor do? Well really nothing. What I need it to do though is free the memory owned by the class. For that I need my own
~Example() {
delete m_pValue;
}
Note: For a situation like this though you'd probably want to go with auto_ptr<T> or the like but I avoided it for demo purposes
So you can do explicit clean up that your instance does. If you allocate (new) memory then you must free it.
The implicit destructor might not do everything. There might have been resources like database connections, File handlers which need to be explicitly closed.
Another important case of an empty explicit destructor is when you derive from a base class.
The base class should always have a virtual destructor otherwise you are were close to a lot of problems due memory leaks.
The implicit destructor will only destroy objects that are members of the class by calling their destructor. If there is any special, additional processing required on destruction of these objects the compiler will not know about it and thus not call these functions before destroying the object.
Also, if you are working with non-RAII code, you might need to release resources like memory, file handles, other OS objects etc before the object itself can be shut down cleanly.
There is also one other special case where you need to provide an implementation of a destructor, namely when you are writing a class that is designed to be a base class and thus has a virtual destructor. Once you explicitly declare the destructor (virtual or not doesn't matter), the compiler will not generate an implicit destructor. So in this case you will have to provide a definition of the destructor, even if it is empty.
Explicit constructors and destructors are very useful in implementing RAII (Resource Acquisition Is Initialization). It is quite possible to free up resources without using a destructor, but then there are ugly concerns, e.g. what will happen if an exception is thrown before the resources are freed.
Sticking resource acquiring tasks in a constructor and resource freeing tasks in a destructor is a simple way to ensure that the resources are freed up when they should be.
I use an explicit destructor in our IO class to ensure that any files (HDF, NetCDF, ASCII/binary) are properly closed. I don't think the default compiler-generated destructor will do that for you.
First, when you want to free the memory assigned to an object in C++, which one is preferred? Explicitly calling destructor or using delete?
Object* object = new Object(...);
...
delete object;
OR
object->~Object();
Second, does the delete operator call the destructor implicitly?
delete implicitly calls the destructor, you don't need (more precisely: shouldn't) call it directly.
A destructor will never release the memory occupied by the object (It may reside on the stack, not on the heap, and the object has no way of knowing -- however, the destructor will delete any memory allocated by the object's components).
In order to free the memory of an object allocated on the heap, you must call delete.
When you write your own class, C++ will provide a default destructor to free the memory allocated by component objects (such as a QString that is a member of your class), but if you explicitly allocate memory (or other resources) in your constructor, be sure to provide a destructor that will explicitly free these resources.
Another general rule regarding your own classes: If you mark any methods virtual, your destructor should be virtual, as well (even if you rely on the default destructor), so that the correct destructor is called for any classes derived from yours.
I prefer neither.
An explicit destructor call is needed very, very rarely, only when you are dissociating memory allocation from object lifetime. You might need it if implementing a custom container class.
An explicit delete is, potentially, a legitimate way to destroy an object dynamically created with a new expression but it should be unnecessary in most application code as it signals a place where potential mismatches between new and delete might occur and areas with potential exception safety issues.
Where an object lifetime is constrained to a block a local variable should normally be preferred as the memory allocation overhead is usually lower and the object will automatically be cleaned up correctly however the block is exited.
{
// ...
Object object( ... );
} // object destructor run, however this block is exited.
If there is some reason that this can't be need (e.g. the object has an excessive static size) or it's lifetime can't be matched to a particular scope, then usually some sort of smart pointer should be used to manage the objects lifetime. The most basic smart pointer which is available in standard C++ is std::auto_ptr which can be used for block scoped dynamically allocated objects but has 'surprising' behaviour on copy and assignment. Something like tr1::shared_ptr (or boost::shared_ptr) are common alternatives where shared ownership is needed.
{
std::auto_ptr<Object> object(new Object(...));
// ...
} // *object destructor run, however this block is exited.
delete is preferred. Just calling the destructor does not free the memory allocated by the new.
Use delete. It calls the objects destructor and then frees allocated memory.
Also, it's not a deconstructor, but a destructor.
Normally you never want to explicitly call the destructor. Just use delete.
Invoking delete will invoke the destructor and then release the memory.
Invoke the destructor explicitly will only invoke the destructor, and not release the memory.
You should therefore almost always call delete: except when you want to invoke the destructor without releasing the memory, e.g. because you constructed the object using placement new.
You should never call the destructor yourself. delete will call it for you
Something else to consider:
since delete calls the destructor internally, it’s an error to do both, i.e. calling the destructor and then delete. So the following code:
Foo* px = new Foo;
// …
px->~Foo();
delete px;
Will produce a nasty bug. Depending on the actions taken in the actual destructor, this may go unnoticed for quite some time, since the compiler actually allows this code. This may lead to subtle, hard to discover bugs.
You should use delete
http://www.parashift.com/c++-faq-lite/dtors.html
When you are using dynamic memory allocation to create the object at that time you can use the delete operator to destroy/delete the object but when you are not using DMA at that time trying to delete an object using delete operator throws error. One way to handle this situation is, writing your own destructor explicitly and calling the destructor using the object to destroy it.
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 '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.
Note that the top-level if statement isn't really part of the generated code; the compiler makes that decision at compile-time.
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.
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."