A detailed description of forced type conversions under the new C + + standard

Source: Internet
Author: User

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_idmust 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_castIt 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_castUsed 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-idMust 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

volatileand 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_castby 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_castThe 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_castTo 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_castOperator 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. dcontains 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_caststhe 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_castis 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_castCan 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_castTypically used to enforce the constant elimination of objects. It's the only way to make this a C++ mandatory transformation of style.

    • reinterpret_castis 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

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.