简体   繁体   中英

What's the difference between static_cast<type> and static_type<type *>?

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> and static_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM