As others have said, there's no reason whatsoever to use void* here. Just declare the struct without defining it in the header. Then only define it in the C file. C is fine with pointers to structs which are merely declared but not defined.
As others have said, there's no reason whatsoever to use void* here. Just declare the struct without defining it in the header. Then only define it in the C file. C is fine with pointers to structs which are merely declared but not defined.
There is almost no reason whatsoever to use void * anywhere other than to write a declaration that is compatible with another one which uses it.
(A pointer to any object is better implemented as a typedef for unsigned char *. This requires a cast in both directions, thus it is safer. At the same time, it is more convenient when you actually want to work with the memory as such: you have bytewise arithmetic and dereferencing.)
> C is fine with pointers to structs which are merely declared but not defined.
Particularly if the secret object is a struct/class then this certainly improves the code (and when the secret isn't such a thing, it can probably be made into one: e.g. a secret array of integers can probably just be a a struct containing an array, possibly a flexible one). Numerous unsafe casts are thereby eliminated.
But it makes no material difference to its organization or semantics. It's still the same PIMPL pattern.
Well, what if the actual class is a template? No matter, you can derive a class from a template, as in:
header: class Impl;
implementation:
class Impl: public std::vector<SomeType> { ... };
People who don't do this and use void* wind up with an implementation that has lots of casts in it, and it's easier to introduce bugs, especially once you get to the point where you have two or more hidden implementations.
Declaring a private and opaque forward decl is very different to VOID* all the things.