Use standard C++
type conversions: static_cast
, dynamic_cast
,, reinterpret_cast
and const_cast
.
static_cast
Usage:static_cast<type_id> (expression)
The operator expression
converts to a type-id
type, but there is no run-time type check to guarantee the security of the conversion. It is mainly used in the following ways:
- The conversion of a pointer or reference between a base class and a derived class in a class hierarchy that is converted to a base class representation by a pointer or reference to a derived class is safe for downstream conversions (a pointer or reference to a base class is converted to a derived class representation) and is unsafe because there is no dynamic type checking
- Used for conversions between basic data types, such as
int
converting to char
. The security of this conversion also needs to be developed to ensure
- To convert a null pointer to a null pointer of the target type
- Convert any type of expression to a
void
type
Note: static_cast
cannot be converted expression
const
, volitale
or __unaligned
properties.
dynamic_cast
Usage:dynamic_cast<type_id> (expression)
The operator expression
converts the type_id
object into a type. type_id
must be a pointer to a class, a reference, or void*
;
Conditional conversions, dynamic type conversions, run-time type security checks (conversion failure returned NULL
):
1. Secure the conversion between the base class and the subclass.
2. You must have a virtual function.
3. Cross-conversion between different subclasses of the same base class. But the result is NULL
.
If type_id
it is a class pointer type, then it expression
must also be a pointer, and if type_id
it is a reference, it expression
must be a reference.
dynamic_cast
It is primarily used for upstream and downstream conversions between class hierarchies , and can also be used for cross-conversion between classes.
The effect is the same when the upstream conversion is performed between class hierarchies dynamic_cast
static_cast
;
The dynamic_cast
ability to type check is more secure than the downstream conversion static_cast
.
dynamic_cast
Used only for pointers and references to objects. When used with polymorphic types, it allows arbitrary implicit type conversions and the reverse process. However, unlike static_cast
in the latter case (note: The reverse process of implicit conversion), the dynamic_cast
operation is checked for validity. That is, it checks whether the transformation returns a valid full object that is requested.
The detection occurs at run time. If the pointer being converted is not a valid full object pointer being requested, the return value is NULL
.
class B{public: int m_iNum; virtualvoid foo();};class D:public B{public: char *m_szName[100];};void func(B *pb){ static_cast<D *>(pb); dynamic_cast<D *>(pb);}
In the preceding code snippet, if you pb
point to an object of a type, it D
pd1
pd2
is the same and is safe for any operation of the two pointer execution D
types;
However, if you pb
point to an B
object of a type, then it will be a pointer to that object, and the operation on it will be unsafe pd1
D
(such as access m_szName
) and will be pd2
a null pointer.
It is also important to note that B
there is a virtual function, otherwise there is a compilation error; static_cast
This is because runtime type checking requires run-time type information, and this information is stored in the virtual function table of the class (the concept of virtual function table, in detail <Inside c++ object model>
), only the class that defines the virtual function has a virtual function table, and no virtual function is defined by a class without a virtual function table.
Also, dynamic_cast
cross-conversion is supported, as shown below.
class a{ public : int m_inum; virtual void f () {}}; class B:public a{}; class D:public a{}; void foo () {B *PB = new B; Pb->m_inum = 100 ; D *PD1 = static_cast <d *> (PB); //compile error D *pd2 = dynamic_cast <d *> (PB); //PD2 is NULL delete PB; }
In the function, the use of the foo
static_cast
conversion is not allowed, the compile-time error, and the use dynamic_cast
of the conversion is allowed, the result is a null pointer.
Reinterpret_cast
Usage:reinterpret_cast<type_id> (expression)
type-id
Must be a pointer, reference, arithmetic type, function pointer, or member pointer. It can convert a pointer to an integer, or an integer to a pointer (a pointer is converted to an integer, the integer is converted to the original type of pointer, and the original pointer value can be obtained).
This operator can be converted between non-related types. The result of the operation is simply a binary copy of the value from one pointer to another pointer. Content that is pointed to between types does not have any type of check and conversion. If the case is a copy from a pointer to an integral type, the interpretation of the content is system-dependent, so any implementation is not convenient. A pointer that is converted to an integer large enough to contain it can be converted back to a valid pointer.
The operator uses more.
( static_cast .
with . reinterpret_cast
comparison, see below)
The operator platform is poorly ported.
Const_cast
Usage:const_cast<type_id> (expression)
The operator is used to modify const
or volatile
attribute the type. In const
addition volatile
to or grooming type_id
, expression
the type is the same.
- The constant pointer is converted into a very pointer, and still points to the original object;
- A constant reference is converted to a very literal reference and still points to the original object;
- A constant object is converted to a very mass object.
It allows a pointer of the subclass type to be converted to a pointer of the parent class type (this is a valid implicit conversion), and can also perform the opposite action: transform the parent class to its subclass.
This conversion type manipulates the properties of the passed object const
, or is set or removed
volatile
and const
type, for example, as shown below.
class B{public: int m_iNum; }void foo(){ const B b1; 100//comile error const_cast<B>(b1); 200//fine }
The above code compiles with an error, because b1
it is a constant object and cannot be changed;
const_cast
by converting it to a very mass object, you can arbitrarily change its data members. Note: b1
and b2
is two different objects.
Compare dynamic_cast vs static_cast
class B { ... };classpublic B { ...};void f(B* pb){ dynamic_cast<D*>(pb); static_cast<D*>(pb); }
That is dynamic_cast
, it can be used for a downward transformation in the inheritance system, converting a base-class pointer to a derived-class pointer, which is more static_cast
secure than stricter. The performance is less dynamic_cast
efficient static_cast
, but static_cast
the mapping can be done on a wider scale, and this unrestricted mapping is accompanied by insecurity. static_cast
The overridden transformation types, in addition to the static navigation of the class hierarchy, include no mapping transformations, narrow transformations (which can result in object slicing, loss of information), VOID*
forced transformations, implicit type transformations, and so on.
Static_cast vs Reinterpret_cast
reinterpret_cast
To map to a completely different type of meaning, this keyword is used when we need to map the type back to the original type . The type we map to is just for the sake of the trick and other purposes, which is the most dangerous of all mappings. (This sentence is C++
the exact words in the programming idea)
static_cast 和 reinterpret_cast
Operator modifies the operand type . They are not reciprocal, static_cast
use type information at compile time to perform transformations, perform necessary checks on transformations (such as pointer out-of-bounds calculations, type checking). Its operands are relatively safe. On the other hand reinterpret_cast
, just to re-interpret the given object's bit model without binary conversion, the example is as follows:
int n=9; double d=static_cast < double > (n);
In the example above, we convert a variable from one int
to another double
. These types of binary expressions are different . To convert an integer 9 to a double integer 9, static_cast
you need to correctly complement the bit for a double integer d
. The result is 9.0
.
And Reinterpret_cast's behavior is different:
int n=9;double d=reinterpret_cast<double & > (n);
This time, the results are different. d
contains useless values after the calculation. This is because only the reinterpret_cast
bits of the copy are copied n
d
, and no necessary analysis is performed.
Therefore, you need to use caution reinterpret_cast
.
Add:
(1) static_cast
: Functionally C
, it is basically as powerful as the type of style conversion, meaning is the same. It has a functional limit. For example, you cannot convert static_cast
C
to a struct
int
type or convert a type to a double
pointer type, as you would with a style conversion. In addition, static_cast
you cannot remove attributes from an expression const
because another new type converter const_cast
has such functionality.
Can be statically resolved out of the type of conversion possibilities, even in the inheritance system, even including multiple inheritance and virtual inheritance, as long as the static resolution can be converted successfully
(2) const_cast
: Used for type-cast-off expressions const
or volatile
properties. By using const_cast
, you are emphasizing to people and compilers that what you want to do through type conversion is simply to change something constness
or volatieness
property. This meaning is constrained by the compiler. If you try const_cast
to use it to complete changes constness
or volatileness
properties, your type conversion will be rejected.
(3) dynamic_cast
: It is used to safely move down type conversions along the inheritance of the class. That is, you can use pointers or dynamic_cast
references that convert exponentially to a base class or to its sibling class, and you can see whether the conversion succeeded. The failed transformation returns a null pointer (when the pointer is type-cast) or throws an exception (when the reference is type-converted).
(4) reinterpret_cast
: Using the type conversion of this operator, the conversion result is almost the execution period definition. Therefore, reinterpret_cast
the code used is difficult to port. reinterpret_casts
the most common use of this is to convert between function pointer types .
# # Four forms of forced transformation in C + + each of these applies to a specific purpose:
dynamic_cast
is primarily used to perform "safe downward Transformation ( safe downcasting
)", 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 it is the only forced transformation that can have significant runtime costs.
static_cast
Can be used to force implicit conversions (for example, non-const
object transformation to const
object, int
transformation to, and double
so on), it can also be used for a number of reverse transformations of such conversions (for example, the void*
pointer is transformed into a typed pointer, the base class pointer is transformed into a derived class pointer ), but it cannot transform an const
object into an non-const
object (only if it const_cast
can), it is closest to C-style
the transformation.
const_cast
Typically used to enforce the constant elimination of objects. It's the only way to make this a C++
mandatory transformation of style.
reinterpret_cast
is intentionally used for the underlying forced transformation, resulting in the implementation of dependent ( implementation-dependent
) (that is, non-portable) results, such as transforming a pointer to an integer. Such a forced transformation should be extremely rare outside of the underlying code.
A detailed description of forced type conversions under the new C + + standard