The four types of conversions in C ++ and whether const_cast can change Constants

Source: Internet
Author: User

We have four specific castingoperators:Dynamic_cast,Reinterpret_cast,Static_castAndConst_cast.
Their format is to follow the new type enclosed between angle-brackets (<>) And immediately after, the expression to be converted between parentheses.

Dynamic_cast <new_type> (expression)
Reinterpret_cast <new_type> (expression)
Static_cast <new_type> (expression)
Const_cast <new_type> (expression)


I. The conversion of the four types in C ++ is summarized as follows:

 
Const_cast <t> (expr)

Cast away the constness)
Const_cast is generally used for pointers or references.
The purpose of removing the const Limitation Using const_cast is not to modify its content.
Remove the const Limitation Using const_cast, usually to allow the function to accept this actual parameter.

Static_cast <t> (expr)

Any implicit type conversion by the compiler can be completed by static_cast.
When a large arithmetic type is assigned to a small type, you can use static_cast for forced conversion.

You can convert a void * pointer to a certain type of pointer.

You can convert a base class pointer to a derived class pointer.
Const cannot be converted to nonconst, which can only be obtained by const_cast.

Reinterpret_cast <t> (expr)
 
"Usually provides a lower-level re-interpretation for the bit mode of the operand" That is to say, the data is re-interpreted in binary format.
Int I;
Char * P = "this is a example .";
I = reinterpret_cast <int> (P );
// In this case, the values of I and P are exactly the same.

Int * IP
Char * Pc = reinterpret_cast <char *> (IP );
// The programmer must remember that the actual object that the PC points to is an int type, not a string.
// If the PC is treated as a character pointer, a running error may occur.
// For example, int Len = strlen (PC );

Dynamic_cast <t> (expr)
Execute the "safe down" transformation operation, that is, it supports identifying pointers or objects pointed to during runtime. This is the only transformation operation that cannot be performed in old languages.


Dynamic_cast is the strictest conversion, followed by static_cast, while reinterpret_cast is the loose. If you encounter a problem that cannot convert an integer into a function pointer, you can solve it as follows:

Reinterpret_cast <lpfun &> (naddress );

Note that lpfun has a "&" symbol, indicating reference. c ++ references are actually implemented using pointers, and these "conversions" are actually pointer conversions, therefore, the compilation can be completed only by adding the reference symbol.


2. You may have had the following questions: const_cast can remove the const attribute of a constant. After removing the const attribute, you should be able to modify the "constant, I found through the debugger that the value in the memory is changed, but when I pass this "constant", the value remains unchanged. It's really weird. I tried it using VC in windows, in Linux, the same is true when using G ++. I thought it had something to do with the compiler's optimization options. It would be useless if I disabled all the optimization options. Why?

I wrote a program for testing:

C ++ code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# Include <iostream>
Using namespace STD;

Void fun (Int & value)
{
Cout <"Fun (VAL) =" <value <Endl;
}

Int main (void)
{
Const int val = 100;

Int * PTR = const_cast <int *> (& Val );
* PTR = 200;
Cout <& Val <Endl;
Cout <PTR <Endl;
Cout <"Val =" <Val <Endl;
Cout <"* PTR =" <* PTR <Endl;

Int & ref = const_cast <Int &> (VAL );
Ref = 300;
Cout <"Val =" <Val <Endl;
Cout <"ref =" <ref <Endl;

Fun (const_cast <Int &> (VAL ));

Return 0;
}

Output:


It can be seen that the printed Address is the same, and the strange thing is that Val is equal to 100, but what is printed through * PTR is the changed 200, and the fun function prints 300, that is, it is referenced and modified once again. Set a breakpoint near the print statement and debug the disassembly:


It can be seen that the system has pre-processed the Val const and replaced it with "64h" (The hexadecimal 64 is the decimal 100 ), that is to say, in the compiled command, Val has been replaced with 100. In fact, adding const only tells the compiler that it cannot be modified rather than cannot be modified. If the programmer does not pay attention to it, an error will be reported, now we use const_cast to remove constants, and then modify them through pointers and references. So we can see that the memory has actually changed when we print the pointer or reference the passing parameter, but to protect the original const feature of the Val variable, the system replaces it with the initial value 100 every time we use Val, ensuring that Val is "immutable. Remember, only when the const qualifier is before the initialized global variable is in. the rodata segment (in Linux) is truly unchangeable, otherwise it can be modified through pointers, although warnings are generated during compilation.

In Linux, the same result is output:



Appendix:

Description of four cast types on msdn:

 

Reinterpret_cast Operator

The reinterpret_cast operator allows any pointer to be converted into any other pointer type. It also allows any integral type to be converted
Any pointer type and vice versa. Misuse of the reinterpret_cast operator can easily be unsafe. Unless the desired conversion is inherently low-level, you should use one of the other cast operators.

 

Dynamic_cast Operator

The expression dynamic_cast (expression) converts the operand expression to an object of type-id. the type-ID must be a pointer or a reference
To a previusly defined class type or a "pointer
To void ".
The type of expression must be a pointer if type-ID is a pointer, or an L-value if type-ID is a reference.

 

Static_cast Operator

The expression static_cast <type-ID> (expression) converts expression to the type of type-id based solely on the types present in the expression.
No run-time type check is made to ensure the safety of the conversion.

 

Const_cast Operator

The const_cast operator can be used to remove the const, volatile, and _ unaligned attribute (s) from a class.


Reference: http://blog.csdn.net/guogangj/archive/2007/03/29/1545119.aspx

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.