tags:

views:

556

answers:

13

My question is simple: What are void pointers for in C++? (Those things you declare with void* myptr;)

What is their use? Can I make them point to a variable of any type?

+17  A: 

Basically, a remnant from C.

What is their use?

In C, they were and are used widely, but in C++ I think they are very rarely, if ever, needed, since we have polymorphism, templates etc. which provide a much cleaner and safer way to solve the same problems where in C one would use void pointers.

Can I make them point to a variable of any type?

Yes. However, as others have pointed out, you can't use a void pointer directly - you have to cast it into a pointer to a concrete data type first.

Péter Török
That makes things... interesting. Thanks for your quick reply :)I know it is probably bad practice but it could be very useful for me in some cases!
Dr. Acula
If you are writing in C++ (and not C), using `void*` is nearly always the wrong thing to do. Why not improve your C++ skills by seeking out the *right* ways to handle these cases?
Tyler McHenry
While I don't disagree that void* should be avoided, as there are usually better ways of doing things in C++, there are still some unusual cases where they're valuable or needed. An example of the latter is determining whether a pair of references are for the same object, when the references are to different parent classes of a multiply-inherited object.
Steven Sudit
@Steven, with multiple inheritance itself being one of the not quite recommended idioms of C++ ;-)
Péter Török
@Péter Török: You're not wrong. The fact that MI can *require* you to cast to `void*` for comparisons is just one indication of how much trouble that language feature can be.
Steven Sudit
@Steven, I did not mean to contradict you either, sorry if my comment was not clear on this. I think we are pretty much in agreement :-)
Péter Török
@Péter Török: No contradiction taken. When I actively coded C++, I managed to almost entirely avoid MI. Now that I'm usually doing C#, which lacks MI but does allow multiple implementation of interfaces, I've started to see the benefits of multiple identities. Too bad the C++ implementation is so painful.
Steven Sudit
+7  A: 

Yes, this is a C construct (not C++-specific) that allows you to declare a pointer variable that points to any type. You can't really do much of anything with such a pointer except cast it back to the real object that it actually points to. In modern C++, void* has pretty much gone out of fashion, yielding in many cases to template-based generic code.

jwismar
+4  A: 

From cplusplus.com:

The void type of pointer is a special type of pointer. In C++, void represents the absence of type, so void pointers are pointers that point to a value that has no type (and thus also an undetermined length and undetermined dereference properties).

This allows void pointers to point to any data type, from an integer value or a float to a string of characters. But in exchange they have a great limitation: the data pointed by them cannot be directly dereferenced (which is logical, since we have no type to dereference to), and for that reason we will always have to cast the address in the void pointer to some other pointer type that points to a concrete data type before dereferencing it.

Raul Agrait
+4  A: 

About one of the few uses that exist for void pointers in C++ is their use in overloading the new operators. All new operators return type void* by definition. Other than that, what others have said is true.

wheaties
+1  A: 

A void pointer can point to anything, as long as its memory :-)

The C standard states that you can convert any pointer to a void-pointer, then cast it back without losing anything.

Patrick
A: 

void ptr is basically an empty box. Fill it with whatever you want but make sure you label it(tupecasting)

Ram Bhat
I think you mean "typecasting", although "tuplecasting" sounds like the name of an exciting new paradigm just waiting to be discovered.
AShelly
I think `tupecasting` is a typo for `upcasting`. Having said that, you cast up to void, down to a specific type.
Steven Sudit
A: 

I use them in my dynamic lists to hold more types of objects (all are pointers).
typedef void* Object; Then when you declare a Object variable you can store any pointer in it. It's more or less usefull depending on the needs.
I find it very usefull when you have to store any pointer somewhere and you can't just derive all your classes from just one. Other than that as the others said it's better to use templates, polimorphism etc.

Sanctus2099
Something like boost::any or boost::variant may be better tasked for most such uses of void*.
Noah Roberts
+1  A: 

A pointer to void is the closest concept to an assembly language pointer. It is a generic pointer that reserves space for an address or location of something (function or datum). As others have stated, it must be cast before it can be dereferenced.

The void pointer is a popular tool for representing Object Orient concepts in the C language. One issue with the void pointer is that the content may not match the receiver's perception. If the caller sets the pointer to point to a square, but the receiving function is expecting a pointer to a cat, undefined and strange things will happen with the pointer is cast.

Thomas Matthews
+3  A: 

Type hiding. It does still have its valid uses in modern C++. Dig through the source code in boost and you'll find a few. Generally the use of a void* is buried very deep within the bowels of a more complex construct that ensures the type safety of the interface while doing black and evil magic within.

Noah Roberts
+2  A: 

They did once in C perform the job of being the pointer-to-anything, a pointer you passed in to libraries and they gave back out to you as userdata. A void* is no use at all without the programmer knowing their context in some fashion, since you don't know what's on the other end, you can't do anything with the data. Except pass the pointer to some other code that does know.

What I don't understand is why people didn't just use undefined types, i.e. opaque pointers. Type safety, user data.

In modern C++, the pointer-to-void is nearly entirely superseded by polymorphism and template-generated generic code. However, you may still have to use them to interface with native C code. To use a void* safely, in any given context, only ever cast one type to a void*. That way, you know for sure what it points to. If you need more types, you could do a quick
struct safevoidptr { base* ptr };
or
struct safevoidptr { void* ptr; int type; };
I believe that dynamic_cast might also be able to convert void* to polymorphic types, although I have never used dynamic_cast, so don't take my word for it.

DeadMG
A: 

Things you could do in C with void, but can't in C++ :

void*'s are automatically converted to other pointer types. (You know its a void* - you gain no type safety from forcing an explicit cast)

Struct* p = malloc( sizeof(Struct) );
// vs C++
Struct* p = (Struct*)malloc( sizeof(Struct) );
// Some will argue that that cast style is deprecated too, and c++ programmers 
// need to actually do this:
Struct* p = reinterpret_cast<Struct*>malloc( sizeof(Struct) );
// See what C++ did there? By making you write Struct a 3rd time, you can now be sure
// you know what you are doing!

void*'s also did indirection counting in C, allowing greater safety when passing pointers to functions that take a pointer to a pointer.

void funcInitializingOutPtr( void** ppOut)
{
  *ppOut = malloc( x );
}

int* out = NULL;
funcInitializingPtr(out);  // C would signal this as an error
funcInitializingPtr(&out); // correct
// vs C++ 
funcInitializingPtr( (void**)&out ); // so much safer needing that exlicit cast.
funcInitializingPtr( (void**)out);   // oops. thanks C++ for hiding the common error
Chris Becke
+1  A: 

Since there are already so many good answers, I'd just provide one of the more common one I saw: template specialization. If I don't recall wrongly, Stroustrup book has an example of this: specializing vector as vector, then having vector to derive (privately) from vector. This way, vector will only contain straightforward easily inlined codes (i.e. call relevant functions from vector). This will reduce the number of duplication when vector is compiled in a program that uses it with many different types of pointers.

Chris Henry
A: 

I belive void* is memory location where you can typecast/Store anything. I some Language Pundit will disagree on this with me. but i have used it successfully in many of my project.

Only problem i see is of typesafety

thatsalok