Both static_cast and reinterpret_cast seem to work fine for casting void* to another pointer type. Is there a good reason to favor one over the other?
问题:
回答1:
Use static_cast
: it is the narrowest cast that exactly describes what conversion is made here.
There’s a misconception that using reinterpret_cast
would be a better match because it means “completely ignore type safety and just cast from A to B”.
However, this doesn’t actually describe the effect of a reinterpret_cast
. Rather, reinterpret_cast
has a number of meanings, for all of which holds that “the mapping performed by reinterpret_cast
is implementation-defined.” [5.2.10.3]
But in the particular case of casting from void*
to T*
the mapping is completely well-defined by the standard; namely, to assign a type to a typeless pointer without changing its address.
This is a reason to prefer static_cast
.
Additionally, and arguably more important, is the fact that every use of reinterpret_cast
is downright dangerous because it converts anything to anything else really (for pointers), while static_cast
is much more restrictive, thus providing a better level of protection. This has already saved me from bugs where I accidentally tried to coerce one pointer type into another.
回答2:
This is a tough question. On the one hand, Konrad makes an excellent point about the spec definition for reinterpret_cast, although in practice it probably does the same thing. On the other hand, if you\'re casting between pointer types (as is fairly common when indexing in memory via a char*, for example), static_cast will generate a compiler error and you\'ll be forced to use reinterpret_cast anyway.
In practice I use reinterpret_cast because it\'s more descriptive of the intent of the cast operation. You could certainly make a case for a different operator to designate pointer reinterprets only (which guaranteed the same address returned), but there isn\'t one in the standard.
回答3:
I suggest using the weakest possible cast always.
reinterpret_cast
may be used to cast a pointer to a float
. The more structure-breaking the cast is, the more attention using it requires.
In case of char*
, I\'d use c-style cast, until we have some reinterpret_pointer_cast
, because it\'s weaker and nothing else is sufficient.
回答4:
My personal preference is based on code literacy like this:
void* data = something;
MyClass* foo = reinterpret_cast<MyClass*>(data);
foo->bar();
or
typedef void* hMyClass; //typedef as a handle or reference
hMyClass = something;
const MyClass& foo = static_cast<MyClass&>(*hMyClass);
foo.bar();
They both do the same in the end, but static_cast seems more appropriate in a middle-ware, app enviroment, while reinterpret cast seems more like something you\'d see in a lower-level library IMHO.