I was experimenting with destructors in C++ with this piece of code:
#include <iostream>
struct temp
{
~temp() { std::cout << "Hello!" << std::endl; }
};
int main()
{
temp t;
t.~temp();
}
I see that "Hello!" is being printed twice. Shouldn't the calling of the destructor free the object and the destructor shouldn't be called again when it goes out of scope? Or is there some other concept?
(I do not intend to do this in practice. I'm just trying to understand what's going on here.)
It happens because you told it to happen. The destructor for an automatic variable is always called when the variable goes out of scope. You also called it. That's two calls total.
Calling an object's destructor does not signal to C++ not to call it again, since in normal execution there is no need to keep track.
The solution is to never manually call your destructor.
Calling the destructor does not free the object.
The destructor is there to clean up the internals of the object and then the object itsself is freed after the destructor finishes.
It's an error to do what you are doing similarly to the way that you can call delete twice on an object but it's an error to do so.
There are only a very few cases where you want to call the destructor manually and this isn't one of them. It's really there for the times you manually construct an object at a memory location using placement new and then need to be able to destruct it without freeing the memory.
I see that "Hello!" is being printed twice. shouldn't the calling of the destructor free the object and the destructor shouldn't be called again when it goes out of scope. Or is there some other concept ?
That's correct.
I must mention that im not intending to do this in practice. Im just trying to understand whats going on here.
You've called the destructor, preparing an object to be destroyed. But this is also done automatically when an object goes out of scope, before it's actually de-allocated.
The thing to understand is this: If you do things that don't make sense, then bad things happen. So don't do things that don't make sense. If you manually call a destructor, the descructor runs. That has no effect on anything else unless the destructor actually does something that has an effect.
You just call the destructor, you don't actually free any memory (it is statically allocated). If you use new and then delete the destructor will only be called once.
Destructor is meant to be called when an object goes out of scope if the object is in the stack as in this case or called when it is explicitly destructed with delete when the object is created on the heap with new operator at the first place.
There is no way for the compiler or the run time system to keep track whether the destructor is called by you manually or not. Also it is a very bad practice to make a call to the destructor.
If you want to do some manual cleaning (other than the object being deleted from memory or getting removed from the stack) before the object getting deleted you may do something like this.
Here you want to allow the client to manually clean things, even before the object gets deleted. But in addition to that, you clean things if client misses to clean it.
class A
{
public:
A() : _closed(false)
{}
~A()
{
close();
}
void close()
{
if (! _closed()) {
// close file handles etc.
}
}
private:
bool _closed
}
The destructor is not the "destroyer" of the object. It's just an ordinary function, but it's called automatically by the language immediately prior to the time of destruction.
It's official name is the destructor, but perhaps it would be more easily understood if we called it the "Before-Destruction" function.
You won't need to call to a destructor, although it is possible to do so. The compiler should implicitly run your destructor for you when an object is no longer used. When objects are created, your constructor is utilized for that object, if it has been declared with specific and initialized values for your class members. When you no longer need your object your destructor will run and delete member variable declarations and their values. This is most useful for languages that don't utilize automatic garbage collection, like C++.
You don't call the destructor explicitly, it is called automatically when the variable goes out of scope (here after the return 0; statement). That's why it is called twice, you call it, and then the system calls it.
If you want to be able to remove an instance of this class yourself, explicitly, you need to dynamically allocate it:
temp *t = new temp;
// do stuff with t...
delete t; // do not forget this, or the constructor is not being called at all
You shouldn't actually call the deconstructor. It is called for you by the runtime support. Hence your calling it once and the runtime support is calling it the second time.
Here is some food for thought on destructors:
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr380.htm
You can explicitly call deconstructors, however it's not recommended, normally they are implicitly called.
The destructor of a class could be invoked:
Explicitly
When the destructor is explicitly invoked using the object of the class, the same way you invoke another member function of the class.
Implicitly
When the object of the class goes out of scope or an object which is created using the new operator is destroyed using the delete operator.
In your sample program, you do both
int main()
{
temp t;
t.~temp(); //1. Calling destructor explictly using the object `t`
return 0;
} // 2. object `t` goes out of scope. So destructor invoked implictly
and that is the reason why you see the destructor being called twice.
As you have aptly thought, the destructor will destroy the resources which were created by constructor. So the destrutor should not be called explicitly, as it will result in destroying the already destroyed resource and that could be fatal.
Related
I was experimenting with destructors in C++ with this piece of code:
#include <iostream>
struct temp
{
~temp() { std::cout << "Hello!" << std::endl; }
};
int main()
{
temp t;
t.~temp();
}
I see that "Hello!" is being printed twice. Shouldn't the calling of the destructor free the object and the destructor shouldn't be called again when it goes out of scope? Or is there some other concept?
(I do not intend to do this in practice. I'm just trying to understand what's going on here.)
It happens because you told it to happen. The destructor for an automatic variable is always called when the variable goes out of scope. You also called it. That's two calls total.
Calling an object's destructor does not signal to C++ not to call it again, since in normal execution there is no need to keep track.
The solution is to never manually call your destructor.
Calling the destructor does not free the object.
The destructor is there to clean up the internals of the object and then the object itsself is freed after the destructor finishes.
It's an error to do what you are doing similarly to the way that you can call delete twice on an object but it's an error to do so.
There are only a very few cases where you want to call the destructor manually and this isn't one of them. It's really there for the times you manually construct an object at a memory location using placement new and then need to be able to destruct it without freeing the memory.
I see that "Hello!" is being printed twice. shouldn't the calling of the destructor free the object and the destructor shouldn't be called again when it goes out of scope. Or is there some other concept ?
That's correct.
I must mention that im not intending to do this in practice. Im just trying to understand whats going on here.
You've called the destructor, preparing an object to be destroyed. But this is also done automatically when an object goes out of scope, before it's actually de-allocated.
The thing to understand is this: If you do things that don't make sense, then bad things happen. So don't do things that don't make sense. If you manually call a destructor, the descructor runs. That has no effect on anything else unless the destructor actually does something that has an effect.
You just call the destructor, you don't actually free any memory (it is statically allocated). If you use new and then delete the destructor will only be called once.
Destructor is meant to be called when an object goes out of scope if the object is in the stack as in this case or called when it is explicitly destructed with delete when the object is created on the heap with new operator at the first place.
There is no way for the compiler or the run time system to keep track whether the destructor is called by you manually or not. Also it is a very bad practice to make a call to the destructor.
If you want to do some manual cleaning (other than the object being deleted from memory or getting removed from the stack) before the object getting deleted you may do something like this.
Here you want to allow the client to manually clean things, even before the object gets deleted. But in addition to that, you clean things if client misses to clean it.
class A
{
public:
A() : _closed(false)
{}
~A()
{
close();
}
void close()
{
if (! _closed()) {
// close file handles etc.
}
}
private:
bool _closed
}
The destructor is not the "destroyer" of the object. It's just an ordinary function, but it's called automatically by the language immediately prior to the time of destruction.
It's official name is the destructor, but perhaps it would be more easily understood if we called it the "Before-Destruction" function.
You won't need to call to a destructor, although it is possible to do so. The compiler should implicitly run your destructor for you when an object is no longer used. When objects are created, your constructor is utilized for that object, if it has been declared with specific and initialized values for your class members. When you no longer need your object your destructor will run and delete member variable declarations and their values. This is most useful for languages that don't utilize automatic garbage collection, like C++.
You don't call the destructor explicitly, it is called automatically when the variable goes out of scope (here after the return 0; statement). That's why it is called twice, you call it, and then the system calls it.
If you want to be able to remove an instance of this class yourself, explicitly, you need to dynamically allocate it:
temp *t = new temp;
// do stuff with t...
delete t; // do not forget this, or the constructor is not being called at all
You shouldn't actually call the deconstructor. It is called for you by the runtime support. Hence your calling it once and the runtime support is calling it the second time.
Here is some food for thought on destructors:
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr380.htm
You can explicitly call deconstructors, however it's not recommended, normally they are implicitly called.
The destructor of a class could be invoked:
Explicitly
When the destructor is explicitly invoked using the object of the class, the same way you invoke another member function of the class.
Implicitly
When the object of the class goes out of scope or an object which is created using the new operator is destroyed using the delete operator.
In your sample program, you do both
int main()
{
temp t;
t.~temp(); //1. Calling destructor explictly using the object `t`
return 0;
} // 2. object `t` goes out of scope. So destructor invoked implictly
and that is the reason why you see the destructor being called twice.
As you have aptly thought, the destructor will destroy the resources which were created by constructor. So the destrutor should not be called explicitly, as it will result in destroying the already destroyed resource and that could be fatal.
I was experimenting with destructors in C++ with this piece of code:
#include <iostream>
struct temp
{
~temp() { std::cout << "Hello!" << std::endl; }
};
int main()
{
temp t;
t.~temp();
}
I see that "Hello!" is being printed twice. Shouldn't the calling of the destructor free the object and the destructor shouldn't be called again when it goes out of scope? Or is there some other concept?
(I do not intend to do this in practice. I'm just trying to understand what's going on here.)
It happens because you told it to happen. The destructor for an automatic variable is always called when the variable goes out of scope. You also called it. That's two calls total.
Calling an object's destructor does not signal to C++ not to call it again, since in normal execution there is no need to keep track.
The solution is to never manually call your destructor.
Calling the destructor does not free the object.
The destructor is there to clean up the internals of the object and then the object itsself is freed after the destructor finishes.
It's an error to do what you are doing similarly to the way that you can call delete twice on an object but it's an error to do so.
There are only a very few cases where you want to call the destructor manually and this isn't one of them. It's really there for the times you manually construct an object at a memory location using placement new and then need to be able to destruct it without freeing the memory.
I see that "Hello!" is being printed twice. shouldn't the calling of the destructor free the object and the destructor shouldn't be called again when it goes out of scope. Or is there some other concept ?
That's correct.
I must mention that im not intending to do this in practice. Im just trying to understand whats going on here.
You've called the destructor, preparing an object to be destroyed. But this is also done automatically when an object goes out of scope, before it's actually de-allocated.
The thing to understand is this: If you do things that don't make sense, then bad things happen. So don't do things that don't make sense. If you manually call a destructor, the descructor runs. That has no effect on anything else unless the destructor actually does something that has an effect.
You just call the destructor, you don't actually free any memory (it is statically allocated). If you use new and then delete the destructor will only be called once.
Destructor is meant to be called when an object goes out of scope if the object is in the stack as in this case or called when it is explicitly destructed with delete when the object is created on the heap with new operator at the first place.
There is no way for the compiler or the run time system to keep track whether the destructor is called by you manually or not. Also it is a very bad practice to make a call to the destructor.
If you want to do some manual cleaning (other than the object being deleted from memory or getting removed from the stack) before the object getting deleted you may do something like this.
Here you want to allow the client to manually clean things, even before the object gets deleted. But in addition to that, you clean things if client misses to clean it.
class A
{
public:
A() : _closed(false)
{}
~A()
{
close();
}
void close()
{
if (! _closed()) {
// close file handles etc.
}
}
private:
bool _closed
}
The destructor is not the "destroyer" of the object. It's just an ordinary function, but it's called automatically by the language immediately prior to the time of destruction.
It's official name is the destructor, but perhaps it would be more easily understood if we called it the "Before-Destruction" function.
You won't need to call to a destructor, although it is possible to do so. The compiler should implicitly run your destructor for you when an object is no longer used. When objects are created, your constructor is utilized for that object, if it has been declared with specific and initialized values for your class members. When you no longer need your object your destructor will run and delete member variable declarations and their values. This is most useful for languages that don't utilize automatic garbage collection, like C++.
You don't call the destructor explicitly, it is called automatically when the variable goes out of scope (here after the return 0; statement). That's why it is called twice, you call it, and then the system calls it.
If you want to be able to remove an instance of this class yourself, explicitly, you need to dynamically allocate it:
temp *t = new temp;
// do stuff with t...
delete t; // do not forget this, or the constructor is not being called at all
You shouldn't actually call the deconstructor. It is called for you by the runtime support. Hence your calling it once and the runtime support is calling it the second time.
Here is some food for thought on destructors:
http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr380.htm
You can explicitly call deconstructors, however it's not recommended, normally they are implicitly called.
The destructor of a class could be invoked:
Explicitly
When the destructor is explicitly invoked using the object of the class, the same way you invoke another member function of the class.
Implicitly
When the object of the class goes out of scope or an object which is created using the new operator is destroyed using the delete operator.
In your sample program, you do both
int main()
{
temp t;
t.~temp(); //1. Calling destructor explictly using the object `t`
return 0;
} // 2. object `t` goes out of scope. So destructor invoked implictly
and that is the reason why you see the destructor being called twice.
As you have aptly thought, the destructor will destroy the resources which were created by constructor. So the destrutor should not be called explicitly, as it will result in destroying the already destroyed resource and that could be fatal.
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.
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."