The difference between dynamic_cast, static_cast, Const_cast and reinterpret_cast

Source: Internet
Author: User
Tags null null

There are two types of C + + conversions: implicit conversions and display transformations.
first, for the implicit conversion, is the standard conversion, in many cases, inadvertently occurs, such as int and float addition, the int type will be implicitly converted to float, this is called the upgrade conversion. Also, the value to the right of the equal sign is converted to the type on the left, and then the value is assigned. There are also class variables passed as arguments to the function:
Class B{public:int num; B (int a) {num=a;}} b Show (b b) {return B;}
Show (5);//An implicit conversion is also occurring here, converting 5 to type B (b) 5;
B b=10;//is OK, there is an implicit conversion, unless the addition of explicit;
Second, display conversion: There are four type conversions in C + +: static_cast, dynamic_cast, Const_cast, and reinterpret_cast.

Here's a little summary of them:

1, static_cast (compiler processing at compile time)

Conversion format:static_cast<type-id> (expression).

Convert expression to Type-id type, type-id and expression must be pointers, references, arithmetic types, or enumeration types. The general conversion (no run-time check) does not provide runtime checks to ensure the security of the conversion.
Mainly used in a few occasions:
(1). Used for the conversion of pointers and references between base and subclass classes in a class hierarchy;
When the upstream conversion: that is, the pointer or reference to the class is converted to the parent class representation, the conversion is safe;
When the downstream conversion: that is, the parent class pointer and reference to the child class representation, this conversion is not safe, need the programmer to ensure;
(2), for the type conversion between the basic data, such as int and Float,char and int, and so on, this is not safe, also need the programmer's guarantee
(3), the conversion of void to the target type of pointer, is and is not safe;
Note: static_cast cannot convert expression to const, volatile, and unaligned attributes.
2. dynamic_cast (determine type during operation)

C programmers probably like to use coercion type conversion, although it's pros and cons, but considering its flexibility we still use the exhilaration. Most of the time we will be converted to success, only a small number of cases will be converted to failure, how to do, this time to use the dynamic_cast. The "small case" here is, if you have multiple inherited class objects, you want to get pointers to objects in some cases, and you convert them to some type, but because of the polymorphism of C + + object types (there can be multiple types), you are not sure that you will succeed (determine their type when running), At this point, dynamic_cast can be leveraged to take advantage of the runtime check mechanism of C + +.
For example:

Class a{...}; Class B:public a{...}; Class C:public b{...}; void Fun1 (b* pb) {A * PA  = (A *) PB; c* PC  
The FUN1 function uses forced type conversion to convert PB to a A * or c*, see what the problem is?
If this is called FUN1:FUN1 (((b*) new C); it's really not a problem.

But if so: Fun1 (new B); The conversion of the type succeeds, thePC will not be null, because the strong turn will always succeed , but not our purpose, because when the use of the PC pointer on the program is tragic, crash (detailed analysis after the specific solution).
If the situation is worse: Fun1 ((b*) 0x00005678); 0x00005678 is a random value
PA,PC is not going to be null, again. Forcing type conversions is always successful, and important things are said two times. But the program definitely crashes when using these two pointers. Of course you can use the exception handling mechanism to handle such errors, but it is a little bit of a small use of the feeling, it is best to find a way to check the success of the type conversion, then Dynamic_ Cast will do the work. Please read the positive explanation below.

dynamic_cast conversion Format:dynamic_cast<type-id> (expression)

To convert expression to a Type-id type, Type-id must be a pointer to a class, a reference to a class, or a void*, and the type of expression and Type-id must be identical;

At run time, the conversion is checked for possible. It can only be applied to pointers or references, and does not support built-in data types, because only pointers and references can be polymorphic, and the assignment and value of the objects will result in the segmentation of the object, not polymorphism. Typically used when converting between a base class and a derived class. The basic usage is as follows:

T1 obj;
t2* POBJ = dynamic_cast<t2*> (&obj); Convert to T2Pointers,failed to return null
t2& refobj = dynamic_cast<t2&> (obj); Convert to T2References,failed throw Bad_cast exception
Note : It is important to note that the type of the converted object, obj, must be a polymorphic type T1, that is, T1 must be publicly inherited from another class, or T1 have virtual functions (inheritance or customization). If the T1 is a non-polymorphic type, the compilation error is reported using dynamic_cast.
Obviously, in order for dynamic_cast to work properly, you must have the compiler support the runtime type information (RTTI).
(1), (up cast) upward transformationAs with the static_cast conversion, it is safe and is a polymorphic foundation that does not require any auxiliary methods and is always successful;
#include <iostream>using namespace Std;class a{};classb:public a{};int main () {b *b=new b; A *a=dynamic_cast<a*> (b);  Safe and success! b *b=dynamic_cast<b*> (b);  Safe and Success!void *vp=dynamic_cast<void *> (c);//success VP points to an object C;system ("pause"); return 0;}
Static_cast and dynamic_cast have the same effect, and this upstream conversion is also implicit conversions; and our definition: a *a=new C; just add a dynamic_cast conversion.
Note One of the following special upstream conversions:easy access When multiple inheritance is ambiguous (resolved with virtual inheritance), there will be problems with the type conversion! For example: B Inherits A,c inheritance A,d inherits AB,
#include <iostream>using namespace Std;class a{};class b:public a{};class c:public a{};class d:public B,public C{}; int main () {d *d=new D; A *a=dynamic_cast<a *> (d);//This is because BC has inherited a, then the conversion from D to a there are two ways to go, DBA or DCA, so that the computer does not know how to go, then the A=null;system ("Pause" ); return 0;}
(2) (down cast) downward transformation:The dynamic_cast has the function of type checking, which is safer than static_cast, and the conversion between polymorphic classes is mainly used dynamic_cast .Because the type provides
Run-time information. If expression is the base class of Type-id, when converted using dynamic_cast, the runtime checks whether expression really points to a pointer of type Type-id, if it is correctly converted, gets the corresponding value, if not, Returns null if it is a reference and throws an exception at run time;
#include <iostream>using namespace Std;class a{};class b:public a{};int Main () {A *a=new B; A *aa=new A; B *a1=dynamic_cast<b*> (a);  A1 Not for Null,a originally pointed to B,safe and success! b *a2=dynamic_cast<b*> (AA)  ///ERROR,AA points to a, does not point to B, returns NULL, i.e. A2=null; System ("pause"); return 0;}

See here, back to the question above: The specific approach is:

* PA  = dynamic_cast<a*>pb;//upcast. if (NULL = = PA) {...}  OK, NOT null; c* pc  = dynamic_cast<c*>pb;//downcast. if (NULL = = PC) {...}   Error, obviously null null;
dynamic_cast < objecttype-id* > (objecttype*)
If you want to successfully convert objecttype* to objecttype-id*, you must have this possibility, which means that the object that objecttype* points to "contains" the object that the objecttype-id* points to. So that we can succeed. For the above example, the C object "contains" a B object, and the B object "contains" a object, if:
A * PA = new B;
So
b* PB = dynamic_cast<b*>pa;//OK.
c* PC = dynamic_cast<c*>pa;//Fail.
If you're not sure about this containment relationship, it's best to use dynamic_cast.
You can actually think of dynamic_cast as a forced type conversion that is more rigorously checked, because "more stringent" can be checked out for errors.
(3) Horizontal transformation of (cross cast):

It is important to note that there is an inheritance relationship when you are in a horizontal transition, and that two classes that do not have an inheritance relationship cannot be converted.

Examples are as follows:

Class Shape {};class Rollable {};class circle:public shape, public Rollable {};class square:public shape {};//cross CA St Failshape *pshape1 = new Square (); Rollable *prollable1 = dynamic_cast<rollable*> (pShape1);//prollable null//cross cast Successshape *pshape2 = new Circle (); Rollable *prollable2 = dynamic_cast<rollable*> (pShape2);//prollable NOT NULL

3, const_cast (compiler processing at compile time)

Conversion format for const_cast: const_cast <type-id> (expression)
The const_cast is used to remove the const, volatile, and __unaligned attributes of a type, primarily for const and volatile conversions. The constant pointer is converted to a very pointer, and still points to the original object, the constant reference is converted to a very literal reference, and the original object is still referenced.

Note that a const object can only call a constant function, a constant function can only be output and cannot change the value of a member property, so here const_cast is required to convert my very own pointer object to do the next step.

 #include <iostream>using namespace Std;class a{public:a (): num (Ten) {cout<< "A" <<ENDL;} int num;}; int main () {const a *a=new A; A *a3=new a;cout<<a->num<<endl;//a->num=100; Error, because a const object does not allow to change the member properties of a class; a *aa=const_cast<a *> (a); Aa->num=100;//ok, after const_cast conversion, AA is not a constant object;cout< <a->num<<endl;const a &a1=*a;//a1->num=200; Error; The reference to a constant object cannot change member properties; A &a2=const_cast<A&> (*a); A2.num=200;cout<<a2.num<<endl;//ok, After const_cast conversion, A2 is not a reference to a constant object;//Now A2 and AA both point to the same object.  A a4=const_cast<a> (*A3); Error, you cannot use const_cast directly to remove this property from non-Const,volatile and nuligned.   Const char* p = "123";   char* C = const_cast<char*> (p);   <span></span><pre name= "code" class= "CPP" > C[0] = 1; Error, the surface of the compiler to remove the const, but the operation of the address of the system is still not allowed to do so. 
Char *pp= "keepgoing"; const char *p1=const_cast<const char *> (PP); system ("pause"); return 0;}

Operation Result:

For a type that is defined as const by itself, even if you remove the const, be careful when you manipulate the content, only R cannot operate W, or it will go wrong.

Const_cast operations cannot be converted between different types. Instead, it simply converts an expression that it acts into a constant. It can convert data that is not a const type to a const type, or remove the const attribute. Try not to use const_cast, if found to call their own function, unexpectedly used const_cast, then quickly stop, reconsider the design bar.
(4) reinterpret_cast (compiler processing at compile time)

Conversion format for reinterpret_cast: reinterpret_cast <type-id> (expression)

Used for conversions that do not have any associations, such as converting a character pointer to an integer number. Allows any pointer type to be converted to another pointer type; it sounds powerful, but it's not reliable. It is primarily used to convert one data type from one type to another. It can convert a pointer to an integer, or an integer to a pointer, in the actual development, the first to convert a pointer to an integer, the integer is converted to the original type of pointer, you can also get the original pointer value, especially open up the system global memory space, need to be used between multiple applications , you need to share with each other, pass this memory space pointer, you can convert the pointer to an integer value, get later, then convert the integer value into a pointer, to do the corresponding operation.


Blog Information Reference:

http://riddickbryant.iteye.com/blog/547361

Http://www.jb51.net/article/55968.htm

Http://www.jb51.net/article/55885.htm

http://bbs.pediy.com/showthread.php?t=196996

Http://www.cnblogs.com/weidagang2046/archive/2010/04/10/1709226.html

http://jetyi.blog.51cto.com/1460128/671256


Thank bloggers for sharing!!

The difference between dynamic_cast, static_cast, Const_cast and reinterpret_cast

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.