Deleting objects in c++
I have a LinkedList with a Node that have a field:
void* _data;
Now, I want to delete this data, but i cant know if the data will be a primitive or an object that was dynamically allocated.
so, 开发者_如何学Goif a write:
~Node() {
delete _node;
}
and the data is an object that was dynamically allocated, will it call the destructor of the object or will i have a memory leak?
So how can I make this work?
Don't do that!
Calling delete
on a void pointer
is an Undefined Behavior.[Reference Below]
Undefined Behavior means that anything can happen, the program might crash sometimes or might work sometimes but you cannot predict its behavior at all times, which is a very bad way of programing.
As you rightly concluded with void*
there is no way that the delete
operator can figure out which class destructor it needs to call, Eventually, leading to a Undefined Behavior.
So how can i make this work?
As I see Your intention of having an void*
pointer is for having a generic Link list implementation. C++ already provides a templated generic link list std::list for this purpose, You can use it as there is no point in re-inventing the wheel and it is most likely that the standard link list implementation will be better than any custom implemented version of a generic link list.
If you would still want to have your own version of the link list. You should implement a generic template link list class just what std::list does.
Have a look at Template Programming.
Reference:
As per C++03 Standard section 5.3.5/3:
In the first alternative (delete object), if the static type of the operand is different from its dynamic type, the static type shall be a base class of the operand’s dynamic type and the static type shall have a virtual destructor or the behavior is undefined. In the second alternative (delete array) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined(FootNote 73).
Foot Note 73)
This implies that an object cannot be deleted using a pointer of type void* because there are no objects of type void
If you need this behavior, use a template. You code, as written, has no way to know what destructor to call.
When _node
has type void*
, delete _node
is always incorrect because the type of the operand used with delete
must always be a pointer to the dynamic type of the object constructed, or to a type that is a base class of that type, providing that the base class type has a virtual destructor. Clearly, void*
cannot fulfil either part of that requirement.
If you are using a void*
you need to find someway of casting back to the original type before calling delete
. An altenrative approach would be to use something like a std::shared_ptr<void>
which can be used in a way where an appropriate deleter is stored at construction (or reset) time and will automatically be called with the node is destroyed.
Deleting a void pointer is dangerous. Compilers may warn or reject your code. The C++ standard says you shouldn't be doing so.
In practice, if the compiler does accept your code, it only frees the memory without calling the destructor.
精彩评论