A summary of the differences between 4 coercion type conversions in C + + _c language

Source: Internet
Author: User
Tags constant inheritance volatile

Objective

Use type conversions for standard C + +: static_cast, dynamic_cast, reinterpret_cast, and const_cast.

    1. Const_cast, the literal understanding is to go to the const attribute.
    2. Static_cast, the name of the understanding is static type conversion. such as int converted to char.
    3. dynamic_cast, the name of the understanding is dynamic type conversion. A polymorphic type conversion between a subclass and a parent class.
    4. Reinterpreter_cast, only the type is redefined, but there is no binary conversion.

First, static_cast

Usage:static_cast (expression)

This operator converts expression to a type-id type, but does not have run-time type checking to guarantee the security of the conversion. It mainly has the following several uses:

(1) Conversion of pointers or references between base classes and derived classes in class hierarchies

It is safe to make an upstream conversion (a pointer or reference to a derived class to a base class representation)

To make a downward conversion (a pointer or reference to a base class is represented by a derived class), it is unsafe because there is no dynamic type checking

(2) For conversions between basic data types, such as converting an int to char. The security of this conversion also needs the developer to ensure that

(3) NULL pointer converted to target type

(4) Convert any type of expression to void type

Note:static_cast cannot convert the const, Volitale, or __unaligned attributes of expression.

Second, dynamic_cast

Usage:dynamic_cast (expression)

This operator converts expression to an object of type type_id. TYPE_ID must be a pointer, reference, or void* of a class;

If the type_id is a class pointer type, then expression must also be a pointer, and if TYPE_ID is a reference, then expression must also be a reference.

Dynamic_cast is mainly used for upstream and downlink transitions between class hierarchies, and for cross conversion between classes.

The effect of dynamic_cast and static_cast is the same in the upstream conversion between class levels;

In the downlink conversion, dynamic_cast has the function of type checking, more secure than static_cast.

Class B
{public
:
 
 int m_inum;
 virtualvoid foo ();
};
 
Class D:public B
{public
 :
 Char *m_szname[100];
 
void func (B *pb)
{
 D *pd1 = static_cast<d *> (pb);
 D *pd2 = Dynamic_cast<d *> (pb);
}

In the preceding code snippet, if PB points to a D-type object, PD1 and PD2 are the same, and any operation of type D for both pointers is safe;

However, if the PB points to an object of type B, then PD1 will be a pointer to the object, and it will be unsafe for the type D to operate (such as access to M_szname), and PD2 will be a null pointer.

Also note: b to have a virtual function, or you will compile an error; static_cast does not have this limitation. This is because Run-time type checking requires Run-time type information. This information is stored in the virtual function table of the class (the concept of virtual function table, in detail), only the class that defines the virtual function has a virtual function table, and there is no class that defines a virtual function without a virtual function table.

In addition, dynamic_cast also supports cross conversion, as shown below.

Class A
{public
:
 int m_inum;
 Virtualvoid f () {}
};
 
Class B:public A
{
 
};
 
Class D:public A
{
 
};
 
void foo ()
{ 
 b *PB = new B; 
 Pb->m_inum = m; 
 D *PD1 = Static_cast<d *> (pb); Compile error 
 D *pd2 = dynamic_cast<d *> (pb);//PD2 is NULL 
 DELETEPB; 
}

In function foo, conversion using static_cast is not allowed and will fail at compile time, whereas using dynamic_cast conversion is allowed and the result is a null pointer.

Third, reinterpret_cast

Usage:reinterpret_cast (expression)

Type-id must be a pointer, reference, arithmetic type, function pointer, or member pointer.

It can convert a pointer to an integer, or you can convert an integer to a pointer (first converts a pointer to an integer, converts the integer to a pointer of the original type, and you get the original pointer value).

This operator is more used.

(static_cast. Compare to. reinterpret_cast, see below)

The operator platform has a portable parity.

Four, const_cast

Usage:const_cast (expression)

This operator is used to modify the const or volatile property of a type. In addition to the const or volatile modification, the type_id and expression are of the same type.

The constant pointer is converted to a very measured 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, and the constant object is converted to a very measured object.

The volatile and const types, for example, are shown below.

Class B
{public
: 
 int m_inum; 
}
 
void foo ()
{
 const B B1; 
 B1.m_inum = 100; Comile error 
 B b2 = const_cast<b> (B1); 
 B2. M_inum = 200; Fine 
}

The code above will error when compiling, because B1 is a constant object and cannot be changed;

By using const_cast to convert it to a very object, you can arbitrarily change its data members. Note: B1 and B2 are two different objects.

V. Comparison

(1) dynamic_cast vs static_cast

Class B 
{ 
 ... 
};
 
Class D:public B 
{ 
 ...
};
 
 
void F (b* pb)
{ 
 d* PD1 = dynamic_cast<d*> (pb); 
 d* PD2 = static_cast<d*> (pb); 
}

If PB really points to an object of type D, then PD1 and pd2 'll get the same value. They'll also get the same value if PB = = 0.

If PB points to a type B and not to the complete D class, then dynamic_cast'll know enough to return zero. However, Static_cast relies on the programmer ' s assertion-PB points to an object of type D and simply returns-a point Er to that supposed D object.

That is, dynamic_cast can be used for the downward transition in the inheritance system, and the base class pointer is converted to a derived class pointer, which is more secure and more rigorous than the static_cast. Dynamic_cast is less efficient than static_cast, but static_cast can complete mappings in a wider range, an unrestricted mapping with no security. In addition to static navigation of class level, static_cast-covered transformation types include no mapping transformation, narrowing transformation (which leads to object slicing, loss of information), forced transformation with void*, implicit type transformation, etc...

(2) static_cast vs reinterpret_cast

Reinterpret_cast is to map to a completely different type of meaning, and this keyword is used when we need to map the type back to the original type. The types we map to are only for myth and other purposes, which is the most dangerous of all mappings. (This sentence is the language of C + + programming Thinking)

The static_cast and reinterpret_cast operators modify the operand type. They are not reciprocal; static_cast uses type information to perform transformations at compile time, performing the necessary instrumentation (such as pointer-crossing calculations, type checking) in the transformation. The operands are relatively safe. Reinterpret_cast, on the other hand, simply explains the bit model of the given object without a binary conversion, as follows:

int n=9; Double D=static_cast < double > (n);
In the example above, we convert a variable from int to double. The binary expressions of these types are different. To convert an integer 9 to a double-precision integer 9,static_cast you need to properly complement the bits with a double-precision 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. After the calculation, D contains the useless value. This is because the reinterpret_cast is simply copying n bits to D, without making the necessary analysis.

Therefore, you need to use reinterpret_cast carefully.

Quote: http://www.cppblog.com/lapcca/archive/2010/11/30/135081.aspx

Add:

(1) Static_cast: The function is basically the same as the C-style conversion is as powerful as the meaning of the same. It has functional limitations. For example, you can't convert a struct to an int type or convert a double type to a pointer type using static_cast like a C-style conversion. In addition, static_cast cannot remove the const attribute from an expression because another new type converter const_cast has such a feature.

Can be statically resolved the type of conversion possibilities, even in the inheritance system, even if the inclusion of multiple inheritance and virtual inheritance, as long as the static resolution can be converted successfully

(2) Const_cast: A const or volatile property used to convert an expression to a type. By using const_cast, you emphasize to people and compilers that what you want to do with type conversion is simply to change the constness or volatieness properties of something. This meaning is constrained by the compiler. If you try to use const_cast to do something other than modify the constness or volatileness attribute, your type conversion will be rejected.

(3) dynamic_cast: It is used to securely type conversions down the inheritance relationship of a class. That is, you can use dynamic_cast to convert a pointer or reference to a base class exponentially a pointer or reference to its derived class or its sibling, and you can see if the conversion was successful. A failed transformation returns a null pointer (when the pointer is converted to a type) or throws an exception (when type conversion is made to the reference).

(4) Reinterpret_cast: Using the type conversion of this operator, the conversion result is almost always the implementation period definition. Therefore, code that uses reinterpret_cast is difficult to migrate. The most common use of reinterpret_casts is to convert between function pointer types.

Examples are as follows:

#include <iostream>
usingnamespace std;
 
Class A 
{public 
: 
 virtualvoid foo () 
 { 
 } 
}; 
 
Class B 
{public 
: 
 virtualvoid foo () 
 { 
 } 
}; 
 
Class C:public A, public B 
{public 
: 
 virtualvoid foo () {} 
}; 
 
void Bar1 (A *pa) 
{ 
 B *pc = dynamic_cast<b*> (PA); 
} 
 
void Bar2 (A *pa) 
{ 
 B *pc = static_cast<b*> (PA);//error
} 
 
void Bar3 () 
{ 
 c C; 
 A *pa = &c; 
 B *PB = static_cast<b*> (static_cast<c*> (PA)); 
} 
 
int main ()
{return
 0;
}

A, BAR1 cannot compile

B, BAR2 cannot compile

C, BAR3 cannot compile

D, BAR1 can run normally, but using the wrong cast method

Answer:

Choose b.

dynamic_cast traverse the inheritance tree at run time, so there is no error at compile time. But because A and B have nothing to do with it, the run-time times are wrong (so a and D are all wrong).

Static_cast: Any type conversion implicitly executed by the compiler can be completed by it. For: (1) Basic type. If you can convert int to double (the compiler performs an implicit conversion), you cannot convert int* to double* (without this implicit conversion). (2) for user-defined types, if two classes are irrelevant, there is an error (so B is correct), and if there is an inheritance relationship, you can make any transition between the base class and the derived class, and there will be no errors during compilation. So BAR3 can be compiled (the C option is wrong).

Summarize

The above is the entire content of this article, I hope the content of this article for everyone's study or work can bring certain help, if you have questions you can message exchange.

Related Article

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.