| computerquip (1892) | |||||
|
Today, I was thinking about the uses of void* pointers and if there was any occasion where it would look better in C++. I couldn't think of any and I thought I'd explain why. In C, the use of void pointers can be extremely useful. It can be used as a universally generic pointer that can point to any type. The limitation to this is that you must know the type that the void pointer was casted from in order to obtain data from it (which usually isn't that bad). Here's example using a simple list struct.
This shows that a struct that resembles a simple list node. Notice that in the struct, we have a dataype of void* that holds our data. One may ask how we hold data if we don't know the data type? There are two answers actually. In actuality, you'll know the data type by the time you create the list so you can implement a list specific to your datatype, especially if they're non-primitive. You can imagine how annoying this would be. Or, my favorite C way, is to use void* pointers that can hold any pointer type! This gives a more dynamic view on basic C containers which you'll find a lot in glib and a few other general C libraries. Another may ask how we handle the data if we don't know what data type it is? There is only one answer: You don't. The purpose of the list above is to handle pointers to data, not data themselves. There are a few rare occasions where handling data using void pointers through abstract functions is considered good but I honestly don't know about them. I'm sure GTK+ does it a few times. NOTE: TODO: FIXME: This isn't exactly what I'm wanting to say and is factually not right. In Win32, they use "window handles" (HWND) which happen to be void pointers to keep the contents of the window struct away from the Win32 developer. Although I'm ready to say you shouldn't do this ever, I don't have the experience to say that. Now, note that this seems rather lumpy. There is no datatype consistency in the list e.g. you can have an integer that links to a struct, etc. Also, as I am a fan of beautifying code as much as possible, you must cast the pointer you wish to give to any of the list functions to void* first. Here at C++, we don't settle for lumpy (actually, we do more often than one would know...) or code uglification (fancy word). If we know the data type at the time of List use, why can't we just pass the datatype itself to the list or use a macro or something? Well in C, we can use macros but even this isn't recommended really and can be rather messy. In C++, we have this awesome thing called templates which are heavily underused and often overused. So, this ugly void pointer struct thingy can be turned into:
Read below if you want, was more of me just rambling... NOTE: Doesn't really feel like an article but whatever... | |||||
|
Last edited on
|
|||||
| Disch (8348) | |||
Even that isn't a really good use of void pointers. Templates are better simulated with macros:
| |||
|
|
|||
| computerquip (1892) | |
| I mentioned it, I just didn't demonstrate it. Wasn't sure how to go about it properly to be honest but it seems pretty simple. | |
|
Last edited on
|
|
| Disch (8348) | |
| that's what I get for skimming and not actually reading. | |
|
|
|
| rapidcoder (681) | |
| void* might be useful for implementation of heterogenous data structures in a library code that need not be coupled tightly to user types. E.g. it must accept any user created object and operate on that. Things like e.g. garbage collector implementation or custom memory allocators, etc. These things often operate on "raw" memory, and the type information is useless there. Templates would only bloat the code. So void* is a good choice, then. | |
|
Last edited on
|
|
| computerquip (1892) | |
| Yeah, after a bit more thought, I don't like the original post.. I speak of it as if void pointers and templates are interchangeable, which in some cases they are but not always. I also seem to be favoring C++ (noted by another friend who read the post). Although there is some useful information, the impression it gives is rather off. I won't take down but, just saying... | |
|
|
|
| rocketboy9000 (562) | |||||
To get compile time encapsulation in C, declare a structure in the header:
and define it in the code:
Someone who #includes thingy.h will not be able to allocate encapsulated_thingies or access members, except through the interface that thingy.h provides. Templates have to be done with either void * or macros with the gnu extension typeof(). EDIT: That may sound offtopic. What I mean is that C cannot provide both templates and encapsulation unless you screw with void pointers. | |||||
|
Last edited on
|
|||||