Cast operation details of four types of cast in C++

  • 2020-04-02 01:46:09
  • OfStack

Q: what is C style conversion? What are static_cast,dynamic_cast, and reinterpret_cast? What's the difference? Why pay attention?

A: conversion means to change the representation of A variable by changing its type to something else. In order to cast a simple object into another object you would use the traditional cast operator. For example, to convert a pointer to a floating point number of type doubole to an integer:
Code:
Inti;
Doubled;

I = (int) d;
Or:

I = int (d);

It works well for simple types with standard defined transformations. However, such converters can also be applied indiscriminately to classes and class Pointers. The ANSI-C++ standard defines four new converters: 'reinterpret_cast','static_cast','dynamic_cast' and 'const_cast' to control the type conversion between classes.
Code:
reinterpret_cast < new_type > (expression)
dynamic_cast < new_type > (expression)
static_cast < new_type > (expression)
const_cast < new_type > (expression)

1 reinterpret_cast

'reinterpret_cast' converts a pointer to another type of pointer. It also allows conversion from a pointer to an integer type. And vice versa. Pointer to a specific address value as an integer value?
This operator can be converted between unrelated types. The result is simply a binary copy of the value from one pointer to another. No type checks or conversions are made between the contents pointed to between types.

If the case is a copy from a pointer to an integer, the interpretation of the content is system-related, so any implementation is not convenient. A pointer that converts to an integer large enough to contain it can be converted back to a valid pointer.

Code:
ClassA {};
ClassB {};

A * A = newA.
B * B = reinterpret_cast < B * > (a);
'reinterpret_cast' treats all pointer casts like a traditional cast.

2 static_cast

'static_cast' allows you to perform arbitrary implicit conversions and reverse conversions. (even though it is not allowed to be implicit)

Applied to a pointer to a class, this means that it allows a pointer of a subclass type to be converted to a pointer of a superclass type (a valid implicit conversion), and at the same time, can perform the opposite: converting a superclass to a subclass.

In this final example, the parent class being converted is not checked for compatibility with the destination type.
Code:
ClassBase {};
ClassDerived: publicBase {};

A = Base * newBase;
Derived * b = static_cast < Derived * > (a);
'static_cast' can be used to perform explicit conversions of type definitions, as well as standard conversions between underlying types, in addition to manipulating type Pointers:

Code:
Doubled = 3.14159265;
Inti = static_cast < int > (d);

3 dynamic_cast

'dynamic_cast' is used only for Pointers and references to objects. When used with polymorphic types, it allows for arbitrary implicit type conversions and the reverse process. However, unlike static_cast, in the latter case (note: the reverse of the implicit conversion), dynamic_cast checks that the operation is valid. That is, it checks to see if the transformation returns a valid full object that was requested.

Detection is performed at run time. If the converted pointer is not a valid full object pointer to the requested object, the return value is NULL.
Code:
ClassBase {virtualdummy () {}};
ClassDerived: publicBase {};

The Base * b1 = newDerived;
The Base * b2 = newBase;

D1 Derived * = dynamic_cast < Derived * > (b1); / / succeeds
Derived * d2 = dynamic_cast < Derived * > (b2); / / fails: returns' NULL '

If a reference type performs a cast and the cast is not possible, an exception type of bad_cast is thrown:
Code:
ClassBase {virtualdummy () {}};
ClassDerived: publicBase {};

The Base * b1 = newDerived;
The Base * b2 = newBase;

Derivedd1 = dynamic_cast < Derived & * > (b1); / / succeeds
Derivedd2 = dynamic_cast < Derived & * > (b2); / / fails: exceptionthrown

4 const_cast

This conversion type manipulates the const property of the passed object, which is either set or removed:
Code:
ClassC {};

A = constC * newC;

C * b = const_cast < C * > (a);
The other three operators cannot modify the constants of an object.
Note: 'const_cast volatilequalifier can also change a type.

--------------------------------------------------------------------

Four types of C++ conversions

I. c-style compulsory transformation is as follows:

(T) expression / / castexpressiontobeoftypeT
Function-style forced transitions use this syntax:
T (expression) / / castexpressiontobeoftypeT
There is no essential difference between the two forms, it is simply a matter of where to put the parentheses. I call these two forms a forced transformation of old-style.

Ii. Four forced transformation forms of C++ :

C++ also provides four new forms of forced transitions (commonly referred to as new style or C++ style forced transitions) :
Const_cast (expression)
Dynamic_cast (expression)
Reinterpret_cast (expression)
Static_cast (expression)

Each is suitable for a specific purpose:

, dynamic_cast is mainly used to perform "safe downward transformation (safedowncasting)", that is, to determine whether an object is a specific type in an inheritance system. It is the only forced transformation that cannot be performed with the old style syntax, and the only forced transformation that can have significant runtime costs.

・ static_cast can be used for forcing implicit type conversion (for example, non - const object into a const object, int transformation into a double, and so on), it can also be used for many such conversion reverse transformation (for example, void * pointer to pointer type, a base class pointer to a derived class pointer), but it can't be a const object into a non - const object (const_cast can only), it is the most close to the C - style transformation.

, const_cast is generally used to force the object to be constant. It is the only C++ style forced transformation that can do this.

, reinterpret_cast is intended to be the result of an underlying forced transformation that results in implementation-dependent (that is, non-portable), for example, converting a pointer to an integer. Such forced transitions should be extremely rare outside of the underlying code.

The forced transformation of the old style is still legal, but the new style is preferable. First, they are easier to identify in your code (both in people and in tools like grep), which simplifies the process of looking for broken type systems in your code. Second, specifying the purpose of each forced transformation more precisely makes it possible for the compiler to diagnose usage errors. For example, if you try to force transitions to eliminate constality with a new style other than const_cast, your code will not compile.

= =
. = = dynamic_cast vs. static_cast
= =

ClassB {... };
ClassD: publicB {... };

Pb voidf (B *)
{
D * pd1 = dynamic_cast < D * > (pb);
D * pd2 = static_cast < D * > (pb);
}

IfpbreallypointstoanobjectoftypeD, thenpd1andpd2willgetthesamevalue. Theywillalsogetthesamevalueifpb = = 0.

IfpbpointstoanobjectoftypeBandnottothecompleteDclass thendynamic_castwillknowenoughtoreturnzero. An static_castreliesontheprogrammer 'sassertionthatpbpointstoanobjectoftypeDandsimplyreturnsapointer TothatsupposedDobject.

That is, dynamic_cast can be used for the downward transformation in the inheritance system, which converts the base class pointer to the derived class pointer, which is stricter and safer than static_cast. Dynamic_cast on the execution efficiency is less than static_cast, but static_cast can complete the mapping on a wider scale, this kind of unrestricted mapping with insecurity. Static_cast transformation type covered in addition to the static navigation class hierarchy, include no mapping transformation, narrowing conversion (section of this kind of transformation leads to the object, loss of information), use VOID * mandatory transformation, implicit type conversion, etc...


= =
. = = static_cast vs. reinterpret_cast
= =

Reinterpret_cast is intended to map to a completely different type, and this keyword is used when we need to map the type back to its original type. The type we map to is just for the purpose of being cryptic and otherwise, which is the most dangerous of all mappings.

The static_cast and reinterpret_cast operators modify the operand type. The static_cast USES the type information to perform the conversion at compile time and perform the necessary checks (such as pointer overstep calculations, type checking) on the conversion. Its operands are relatively safe.

Intn = 9; Doubled = static_cast < A double > (n);

In the above example, we convert a variable from int to double. These types of binary expressions are different. To convert the integer 9 to the double integer 9, the static_cast needs to properly complement the bits for the double integer d. The result is 9.0.

Intn = 9;
Doubled = reinterpret_cast < Double & > (n);

This time, the result is different. After the calculation,d contains the null value. This is because reinterpret_cast simply copies the bits of n to d without the necessary analysis.

Conclusion:

There are four casts.
1, static_cast, support subclass pointer to the parent pointer conversion, and adjust the value of the pointer according to the actual situation, and vice versa, but will give a compilation warning, it is the most similar to the c-style "cast", generally speaking, it can be considered safe;

2. Dynamic_cast, support the conversion of parent pointer to subclass pointer, and adjust the value of pointer according to the actual situation, different from static_cast, it does not support the other way around, will lead to compilation errors, this conversion is the safest conversion;

3, reinterpret_cast and support any conversion, but just as its name as described in the "explanation", not to make any adjustments, the value of the pointer can do with it "deliberately mispresents", but it's clear that it is the most unsafe conversion, use it, you'll have to mind, what you're doing;

4. Const_cast. This transformation strips an object of its const property, which allows you to make changes to constants.


Related articles: