These four operators:
Static_cast, const_cast, dynamic_cast, and reinterpret_cast
Static_cast
You only need to know that you are used to writing these operators,
(Type) Expression
Now you should always write like this:
Static_cast <type> (expression)
For example, suppose you want to convert an int to a double type so that the expression containing the int type variable can generate
The result of a floating point value. If you use C-style type conversion, you can write as follows:
Int firstnumber, secondnumber;
...
Double result = (double) firstnumber)/secondnumber;
If you use the new type conversion method, you should write as follows:
Double result = static_cast <double> (firstnumber)/secondnumber;
Such type conversion is easy to recognize for humans and programs.
Static_cast is basically as powerful as C-style type conversion and has the same meaning. It also has functions
. For example, you cannot use static_cast to convert struct to an int class like a C-style type conversion.
Type or convert the double type to the pointer type. In addition, static_cast cannot remove the const from the expression.
Because another new type conversion operator const_cast has this function.
Const_cast
Const_cast is used for type conversion
The const or volatileness attribute of the expression. By using const_cast, you emphasize your communication to people and the compiler.
All you want to do is to change the constness or volatileness attributes of some things. This meaning is edited
Constraints on the interpreter. If you try to use const_cast to modify the constness or volatileness attributes
Otherwise, your type conversion will be rejected.
The following are some examples:
Class widget {...};
Class specialwidget: Public widget {...};
Void Update (specialwidget * psw );
Specialwidget SW; // SW is a non-const object.
Const specialwidget & CSW = Sw; // CSW is a reference of SW.
// It is a const object
Update (& CSW); // error! A const specialwidget * variable cannot be passed
// Provide a function for processing specialwidget * type variables
Update (const_cast <specialwidget *> (& CSW ));
// Correct. The const of CSW is displayed as a conversion (
// The CSW and SW variable values are updated.
// Functions can be updated)
Update (specialwidget *) & CSW );
// Same as above, but it is more difficult to recognize
// C-style type conversion
Widget * PW = new specialwidget;
Update (PW); // error! PW is a widget *,
// The UPDATE function processes the specialwidget * type.
Update (const_cast <specialwidget *> (PW ));
// Error! Const_cast can only be used.
// Constness or volatileness .,
// It cannot be used for type conversion to the inherited subclass.
So far, the most common purpose of const_cast is to convert the const attribute of an object.
Dynamic_cast
It is used to safely move down the inheritance relationship of the class.
Convert the row type. This means that you can use dynamic_cast to convert the pointer or reference to the base class to point to its derivation.
Class or its sibling class pointer or reference, and you can know whether the conversion is successful. If the conversion fails, a null pointer is returned.
When the pointer is converted to a type, or an exception is thrown (when the reference is converted to a type ):
Widget * PW;
...
Update (dynamic_cast <specialwidget *> (PW ));
// Correct. Pass the pointer to the update function.
// Is the PW pointer pointing to the specialwidget variable type
// If PW does point to an object,
// Otherwise, null pointers will be made when the previous one is passed.
Void updateviaref (specialwidget & RSW );
Updateviaref (dynamic_cast <specialwidget &> (* PW ));
// Correct. Pass to updateviaref Function
// Specialwidget PW pointer, if PW
// It does point to an object
// Otherwise, an exception is thrown.
Dynamic_casts is limited in helping you browse the hierarchy of inheritance. It cannot be used for types that lack virtual functions
(See the M24 clause), you cannot use it to convert constness:
Int firstnumber, secondnumber;
...
Double result = dynamic_cast <double> (firstnumber)/secondnumber;
// Error! No inheritance relationship
Const specialwidget SW;
...
Update (dynamic_cast <specialwidget *> (& SW ));
// Error! Dynamic_cast cannot be converted.
// Remove Const.
If you want to convert data types without inheritance relationships, you may think of static_cast. To remove
Const, you must use const_cast.
Reinterpret_cast
The most common purpose of reinterpret_casts is to convert between function pointer types. For example, assume that you
There is a function pointer array:
Typedef void (* funcptr) (); // funcptr is a pointing function
// Pointer. This function has no parameters.
// Return value type is void
Funcptr funcptrarray [10]; // funcptrarray is
// Array of 10 funcptrs pointers
Let's assume that you want (for some inexplicable reason) to store a pointer pointing to the following function
Funcptrarray array:
Int dosomething ();
You can't do it without converting the type, because the dosomething Function
There is an error type. The function return value in the funcptrarray array is of the void type, while dosomething
The Return Value of the function is of the int type.
Funcptrarray [0] = & dosomething; // error! Type Mismatch
Reinterpret_cast allows you to force the compiler to look at them in your way:
Funcptrarray [0] = // This compiles
Reinterpret_cast <funcptr> (& dosomething );
The code for converting function pointers cannot be transplanted (C ++ does not guarantee that all function pointers are used in the same method table.
In some cases, such a conversion will produce incorrect results (see section m31), so you should avoid conversion.
Function pointer type, unless you are at a critical moment in the back-to-back and sharp knife frame throat. A sharp knife. An extraordinary charge
.
Summary
If the compiler you use lacks support for the new type conversion method, you can use the traditional type conversion method
For static_cast, const_cast, and reinterpret_cast. You can also use the macro below to simulate the new
Type conversion Syntax:
# Define static_cast (type, expr) (type) (expr ))
# Define const_cast (type, expr) (type) (expr ))
# Define reinterpret_cast (type, expr) (type) (expr ))
You can use it like this:
Double result = static_cast (double, firstnumber)/secondnumber;
Update (const_cast (specialwidget *, & SW ));
Funcptrarray [0] = reinterpret_cast (funcptr, & dosomething );
These simulations are not as secure as real operators, but when your compiler supports new types of conversions
They can simplify the code upgrade process.
There is no easy way to simulate dynamic_cast operations, but many function libraries provide functions that are safe
Type conversion between the derived class and the base class. If you do not have these functions and you have to perform such type conversion
You can also return to the C-style type conversion method, but you will not be able to know whether the type conversion fails.
Of course, you can also define a macro to simulate the dynamic_cast function, just like simulating other type conversions:
# Define dynamic_cast (type, expr) (type) (expr)
Remember, this simulation does not fully implement the dynamic_cast function. It cannot know whether the conversion is lost.
Failed.
I know, yes, I know that the new type conversion operator is not very beautiful and it is very troublesome to type on the keyboard. For example
If you find that they look really annoying, C-style type conversion can still be used and valid. However
It is because the new type conversion operator lacks aesthetics to make up for its shortcomings in meaning accuracy and identifiability. And,
Programs that use new type delimiters are more easily parsed (either for humans or for tool programs) and they allow Compilation
The server detects errors that cannot be found. These are the strong reasons to give up the C-style type conversion method. And
There are three reasons: Maybe it is a good thing to make the type conversion operator not beautiful and to make it difficult to type.