[Conversion] C ++ standard conversion operator const_cast and operator const_cast
The const_cast Delimiter is the const or volatile qualifier used to remove the variable.
For a const variable, we cannot modify its value, which is the most direct manifestation of this qualifier. But what should we do if we want to modify its content against its limits?
The following code clearly fails to reach the goal:
const int constant = 10;int modifier = constant;
Because the modification to the modifier does not affect the constant, it implies that the const_cast conversion character should not be used in the object data, because the two variables/objects obtained from the conversion are not correlated.
Only using pointers or references to direct variables to the same address is the solution. Unfortunately, the following code cannot be compiled in C ++:
const int constant = 21;int* modifier = &constant // Error: invalid conversion from 'const int*' to 'int*'
(The above code can be compiled in C, and a warning is obtained at most. In C, you can start to confuse the data in constant in the previous step)
It is not acceptable to assign a constant to a non-const reference.
const int constant = 21;int& modifier = constant;// Error: invalid initialization of reference of type 'int&' from expression of type 'const int'
So const_cast came out to eliminate const, in order to cause chaos in the program world.
The following code is successfully compiled:
const int constant = 21;const int* const_p = &constant;int* modifier = const_cast<int*>(const_p);*modifier = 7;
Why remove the const limitation?
As we can see in the previous code, we cannot modify constant, but we can re-assign values to modifier.
But is the program world really messy? Have we actually modified the constant value through modifier? Is it true that C ++ has gone to the const to modify the data of the const variable?
If we print the result:
cout << "constant: "<< constant <<endl;cout << "const_p: "<< *const_p <<endl;cout << "modifier: "<< *modifier <<endl;/**constant: 21const_p: 7modifier: 7**/
The original value of constant is retained.
But they do point to the same address:
cout << "constant: "<< &constant <<endl;cout << "const_p: "<< const_p <<endl;cout << "modifier: "<< modifier <<endl;/**constant: 0x7fff5fbff72cconst_p: 0x7fff5fbff72cmodifier: 0x7fff5fbff72c**/
This is a strange thing, but it is a good thing: const in C ++ is const, which is the constant change in the outside world. Otherwise, it would be messy, and the const would have no significance.
The ibm c ++ Guide calls "modifier = 7;" "Undefined Behavior )". The so-called undefined statement does not have clear provisions in the Standard C ++, And the compiler determines how to handle the statement.
The Left shift operation of bitwise operations can also be considered an undefined action, because we are not sure whether it is logical left shift or arithmetic left shift.
For example, the following statement: v [I] = I ++; is also an undefined behavior, because we do not know whether to perform auto-increment first or to find the position in the array first.
What we can do for undefined behaviors is to avoid such statements. For const data, we must make sure that the value of const data is not re-assigned.
If we don't want to modify the value of the const variable, why should we go to const?
The reason is that we may call a function whose parameter is not const, but the actual parameter to be passed in is const, but we know that this function will not modify the parameter. Therefore, we need to use const_cast to remove the const limitation so that the function can accept this actual parameter.
#include <iostream>using namespace std;void Printer (int* val,string seperator = "\n"){ cout << val<< seperator;}int main(void) { const int consatant = 20; //Printer(consatant);//Error: invalid conversion from 'int' to 'int*' Printer(const_cast<int *>(&consatant)); return 0;}
The cause of this situation may be that the method we call is written by someone else. Another reason I can think of is that when the const object wants to call its own non-const method, because in the class definition, const can also be used as an identifier for function overloading.
Removing the const attribute using const_cast does not actually change the const attribute of the original class type (or basic type). It only provides an interface (pointer or reference ), this interface allows you to change the type value. Maybe this is one of the reasons why const_cast can only convert pointers or references.