So far I understand that static_cast
is a compile time action that somehow analyzes the memory of the entity and tries to convert it to the specified object.
I see static_cast used extensively as static_cast<T *>
. What's the reason for this? Is it because the compiler needs a pointer to check the memory layout of the object?
example:
union U { int a; double b; } u;
void* x = &u; // x's value is "pointer to u"
double* y = static_cast<double*>(x); // y's value is "pointer to u.b"
char* z = static_cast<char*>(x); // z's value is "pointer to u"
For static_cast<T>
this fails however:
double yy = static_cast<double>(u); error: cannot convert 'union U' to 'double' without a conversion operator
I spoted this type of casting first in the use of classes and looks like it is more used there.
Derived * d = new Derived();
Base * b = static_cast<Base *>(d);
However the same question remains:
Base b1 = Base();
Derived d2 = Derived();
b1 = static_cast<Base>(d2);
// No error here
Can I please receive a detail explanation of how static_cast works behind the scenes and how it relates to memory (thus objects) and (if neccessary) the instructions that take place?
It might be helpful to consider two different use cases for static_cast
: one for converting non-pointer types to one another, and one for converting pointer types to one another.
When converting non-pointer types to one another, static_cast
has the meaning of "do the kind of conversion that you would do if you initialized an object of the target type from the source value." So, for example, in this code:
int aASCII = 64;
cout << static_cast<char>(aASCII) << endl; // Prints 'A'
the static_cast<char>(aASCII)
means "give me the char
value I would get here if I were to initialize a new char
value to aASCII
." It's analogous to doing the following:
int aASCII = 64;
char temp = aASCII;
cout << temp << endl;
Similarly, consider this code:
int total = 137;
int numItems = 42;
cout << static_cast<double>(total) / numItems << endl;
the static_cast<double>(total)
bit means "pretend that total
is a double
here when doing the division." It's analogous to writing
int total = 137;
int numItems = 42;
double temp = total;
cout << temp / numItems << endl;
With that in mind, why doesn't this code compile?
double yy = static_cast<double>(u); // Oops!
The reason why is that this is kinda sorta is like writing
double temp = u; // Oops, doesn't compile
double yy = temp;
Here, this won't compile because you can't initialize a double
to a variable of union
type U
.
The use of static_cast
with pointers uses a different set of rules. When working with pointers, static_cast
means "please pretend the pointer points at an object of the type I want it to point at, but only if there's some plausible universe in which that could work." So, for example, this is perfectly legal:
Base* ptr = new Derived;
Derived* dPtr = static_cast<Derived*>(ptr);
Here, this says "I have a pointer of type Base*
. There is a plausible world in which it really points to a Derived
. Please convert the pointer to a Derived*
, but don't do any runtime checks to make sure this is safe. I'm aware that if this doesn't actually point at a Derived
, then Bad Things will happen."
You couldn't, however, write this:
float* ptr = new float[137];
Derived* dPtr = static_cast<Derived*>(ptr); // Error!
This won't work because there's no way for a pointer of type float*
to point at a Derived
object (without doing something really horrible to some pointer at some point in time).
The reason that your code
double* y = static_cast<double*>(x); // y's value is "pointer to u.b"
is fine is because x
is a void*
, which can point at any (non-function) entity, so it's plausible that it could point at a double
.
What's the difference between
static_cast<type>
andstatic_type<type *>
?
type
and type*
are different types. First cast converts to one type and second cast converts to the other type.
I see static_cast used extensively as
static_cast<T *>
. What's the reason for this?
Because probably in those cases the intention is to convert to the type T*
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.