void* and destructors

Started by
16 comments, last by garyfletcher 18 years, 9 months ago
It seems to be the case that when I keep a void* pointer to a C++ class, the destructor doesn't get called when I delete that object -- is that right? It seems reasonable, but is there any way to get around it besides keeping a separate variable that tells you what type of object the pointer points to, and then casting it immediately before deleting it? (obviously the ideal methods is not to use void* at all but use a common base class that everything else derives from, but I would quite like to be able to point to char arrays as well as CMyClass or whatever)
Advertisement
Calling delete on a pointer to a class type cast to a void * has undefined behavior. It will probably just deallocate the memory, but may corrupt your heap. I'd strongly suggest rethinking your design so that you don't use void * at all.
delete([])ing a void * is undefined behaviour. Don't do it. Why would you want a variable to point to either a char array or a MyClass? They have absolutely nothing in common so everytime you accessed the variable you'd have to check what type it is. If you're trying to do generic programming then use templates. If you're trying to do object oriented programming then use inheritence. If you're trying to do anything else then leave the type system intact and don't use the void * abomination*.

Enigma

* yes "abomination" is a bit strong, void *s do have some uses.
If you could explain exactly what your trying to do i'm sure one of us will suggest a much better alternative.

I'm guessing you are trying to separate allocation/deallocation and construction/destruction for some reason correct?
Quote:Original post by Enigma
delete([])ing a void * is undefined behaviour. Don't do it. Why would you want a variable to point to either a char array or a MyClass? They have absolutely nothing in common so everytime you accessed the variable you'd have to check what type it is. If you're trying to do generic programming then use templates. If you're trying to do object oriented programming then use inheritence. If you're trying to do anything else then leave the type system intact and don't use the void * abomination*.

Enigma

* yes "abomination" is a bit strong, void *s do have some uses.



I'm implementing a datafile system, so some data items will just be strings, some will be 3D meshes, some will be sound effects. It's sort of based upon Allegro's system, if you're familiar with that, where the function making use of the data item knows what type it's looking for, so can cast it. I'm actually trying to be a bit safer than that - I actually have overloaded methods GetDataItem(...) one for each supported data type, and if you ask for a pointer to a sound file but the item is actually a mesh then it returns NULL (so I have all the information necessary to cast my void* pointer to the right type before deleting it, I just wondered if there was an easier way)
Discriminated Unions. (Part 2, Part 3). Boost also has a discriminated union type called boost::variant.

Enigma
Quote:Original post by AndyGeers
It seems to be the case that when I keep a void* pointer to a C++ class, the destructor doesn't get called when I delete that object -- is that right? It seems reasonable, but is there any way to get around it besides keeping a separate variable that tells you what type of object the pointer points to, and then casting it immediately before deleting it? (obviously the ideal methods is not to use void* at all but use a common base class that everything else derives from, but I would quite like to be able to point to char arrays as well as CMyClass or whatever)
If you want to be able to point to char arrays as well, then:
Make an empty base class "CMyBaseClass".
Make a simple class "CMyCharArrayClass" that only has a char array as it's private member and define the [] operators. Write whatever other methods you require in this class.
Derive CMyCharArrayClass from CMyBaseClass.
Derive CMyClass from CMyBaseClass.

Now, only deal with CMyBaseClass pointers.
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
Quote:Original post by AndyGeers
I'm implementing a datafile system, so some data items will just be strings, some will be 3D meshes, some will be sound effects.


I see no reason to create a single class which contains a single void pointer to any number of discrete objects. You might want to consider using an abstract factory.


EDIT: Should be 'contains a single void pointer'

[Edited by - Helter Skelter on July 9, 2005 6:19:54 PM]
templates..it's the future!!!
Gary.Goodbye, and thanks for all the fish.
Quote:Original post by AndyGeers
I'm implementing a datafile system, so some data items will just be strings, some will be 3D meshes, some will be sound effects. It's sort of based upon Allegro's system, if you're familiar with that, where the function making use of the data item knows what type it's looking for, so can cast it. I'm actually trying to be a bit safer than that - I actually have overloaded methods GetDataItem(...) one for each supported data type, and if you ask for a pointer to a sound file but the item is actually a mesh then it returns NULL (so I have all the information necessary to cast my void* pointer to the right type before deleting it, I just wondered if there was an easier way)


Do you need to delete any of the items early? Or are you just looking for garbage collection?

If you're just looking to clean up objects when the app exits, why not use smart pointers at the point of instantiation, and when the instantiator goes out of scope, it will automatically delete all your dynamically created class objects. Then all you have to do is keep track of your arrays.

The point of instantiation is the key, though. That's where you know the type of what it is you're creating.

Really, if all you're doing is keeping the list of (void *) around for deletion purposes, it sounds like you're wanting garbage collection... nothing more.
my_life:          nop          jmp my_life
[ Keep track of your TDD cycle using "The Death Star" ] [ Verge Video Editor Support Forums ] [ Principles of Verg-o-nomics ] [ "t00t-orials" ]

This topic is closed to new replies.

Advertisement