views:

198

answers:

9
+3  Q: 

deleting an object

Hi,

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?

Thanks,

+2  A: 

You should never call the destructor yourself. delete will call it for you

Philippe Leybaert
Make that "almost never".
anon
If you do, you should ask yourself if your design isn't flawed
Philippe Leybaert
@Philippe Invoking the destructor directly is used to destroy objects which were instantiated using "placement new".
ChrisW
Then you'd better use a compiler which supports **placement delete**.
Philippe Leybaert
@Philippe: What do you mean?
GMan
I think that placement delete isn't needed when you're using simple [placement new](http://www.research.att.com/~bs/bs_faq2.html#placement-delete) into a preallocated buffer, whose lifetime you manage separately.
ChrisW
It's not needed, but it can be used for that purpose, and it's a cleaner solution than calling the destructor directly.
Philippe Leybaert
@Chris @Philippe: I'm just confused because there is no such thing as placement delete.
GMan
@GMan: yes there is. Check Google...
Philippe Leybaert
@Philippe: There is no placement delete expression unlike new which does have an optional placement form. You can define a placement form of `operator delete` but this does not destroy objects, it is called when it matches an `operator new` in a new expression and the object construction fails after the memory allocation succeeds to correctly deallocate the allocated raw memory. If a placement new expression succeeds then the correct way to destroy the object is with an explicit call to the destructor followed by a matching deallocation (if applicable).
Charles Bailey
+4  A: 

delete is preferred. Just calling the destructor does not free the memory allocated by the new.

Amardeep
+3  A: 

Use delete. It calls the objects destructor and then frees allocated memory.

Also, it's not a deconstructor, but a destructor.

Kotti
+10  A: 

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.

Jen
+4  A: 

Normally you never want to explicitly call the destructor. Just use delete.

Carl Norum
+1  A: 

You should use delete

http://www.parashift.com/c++-faq-lite/dtors.html

Cade Roux
+4  A: 

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.

ChrisW
+2  A: 

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.

Konrad Rudolph
+7  A: 

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.
Charles Bailey
+1 for mentioning hazards of manual lifetime management, although I would humbly suggest changing the example from auto_ptr to shared_ptr in order not to encourage anyone unfamiliar with its intricacies to use auto_ptr.
Niklas