Differences and Applications of static_cast, dynamic_cast and reinterpret_cast

Source: Internet
Author: User

In fact, it is not just a repost, but also a fusion

One question for today is: # include <iostream>
Using namespace STD;

Class bclass
{
Public:
Bclass (){};
Virtual ~ Bclass (){};
Virtual void output (int I) {cout <"bclass: ouput is" <I <Endl ;}

};
Class son1: Public bclass
{
Public:
Son1 (){};
~ Son1 (){};
Void output (int I) {cout <"son1: ouput is" <I <Endl ;}

Void output2 () {cout <"son1: ouput2" <Endl ;}
};
Class son2: Public bclass
{
Public:
Son2 (){};
~ Son2 (){};
Void output (int I) {cout <"son2: ouput is" <I <Endl ;}

Void output2 () {cout <"son2: ouput2" <Endl ;}
};

Int main ()
{
// Bclass B;

Bclass * B = new son2 ();
// B-> output (1 );
Son1 * S1 = static_cast <son1 *> (B); // static_cast only performs type check during static state.
// Son1 * S1 = (son1 *) (B );

If (S1)
{
S1-> output (1 );
S1-> output2 ();

}

S1 = dynamic_cast <son1 *> (B); // at this time, it is null. during runtime, it will check that B is actually of son2, so it will not pass
If (S1)
{
S1-> output (2 );
S1-> output2 ();

}
}

The following is the cause of the search process --------------------------------------------------

From: http://yvqvan.blog.163.com/blog/static/2541510320092278162981/

Use the Standard C ++ type conversion OPERATOR:Static_cast, Dynamic_cast, reinterdivt_cast, and const_cast.

3.1
Static_cast

Usage:Static_cast<Type-ID> (exdivssion)

This operator converts exdivssion to the Type-ID type, but there is no runtime type check to ensure the conversion security. It has the following usage:
① It is used to convert pointers or references between classes and subclasses in the class hierarchy.
It is safe to perform upstream conversion (converting the pointer or reference of a subclass to a base class;
When performing a downstream conversion (converting a base class pointer or reference to a subclass), it is not safe because there is no dynamic type check.
② It is used for conversion between basic data types. For example, convert int to Char and convert int to enum. The security of such conversions must also be ensured by developers.
③ Convert a null pointer to a null pointer of the target type.
④ Convert any type of expression to void type.

Note:Static_castThe const, volitale, or _ unaligned attribute of exdivssion cannot be converted.

3.2 dynamic_cast
Usage: dynamic_cast <type-ID> (exdivssion)
This operator converts exdivssion to an object of the Type-ID type. Type-ID must be a class pointer, class reference, or void *;
If type-ID is a class pointer type, exdivssion must also be a pointer. If type-ID is a reference, exdivssion must also be a reference.

Dynamic_cast is mainly used for upstream and downstream conversions between classes, and can also be used for cross conversions between classes.
When performing upstream conversion between classes,

Dynamic_cast andStatic_castThe results are the same;
When performing a downstream conversion, dynamic_cast has the type check function.Static_castMore secure.
Class B {
Public:
Int m_inum;
Virtual void 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 above Code segment, if PB points to a D-type object, pd1 and Pd2 are the same, and it is safe to execute D-type operations on these two pointers;
However, if PB points to a B-type object, pd1 will be a pointer to this object, it is not safe to perform operations of the D type (for example, to access m_szname ),
Pd2 is a null pointer.

Note: B must have virtual functions; otherwise, compilation errors may occur;Static_castThere is no such restriction.
This is because the runtime type check requires runtime type information, which is stored in the virtual function table of the class (
For more information about the concept of virtual function tables, see). Only classes that define virtual functions have virtual function tables,
Classes that do not define virtual functions do not have virtual function tables.

In addition, dynamic_cast also supports cross cast ). The following code is used.
Class {
Public:
Int m_inum;
Virtual void F (){}
};

Class B: Public {
};

Class D: Public {
};

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 function Foo, useStatic_castConversion is not allowed,

An error occurs during compilation. The conversion using dynamic_cast is allowed and the result is a null pointer.

3.3 reindivter_cast
Usage: reindivter_cast <type-ID> (exdivssion)
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 (first, convert a pointer to an integer,
You can also obtain the original pointer value after converting the integer to the original type ).

This operator is used in many ways.

3.4 const_cast
Usage: const_cast <type-ID> (exdivssion)
This operator is used to modify the const or volatile attributes of the type. Apart from the const or volatile modifier, The type_id and exdivssion types are the same.
Constant pointers are converted to non-constant pointers and still point to the original object;
Constant reference is converted to a non-constant reference and still points to the original object. Constant object is converted to a non-constant object.

Voiatile and const classes. Take the following example:
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 above code will report an error during compilation, because B1 is a constant object and cannot be changed;
Using const_cast to convert it into a constant object, you can change its data members at will. Note: B1 and B2 are two different objects.

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

From http://hi.baidu.com/yueyuwangzi/blog/item/49dd8bcf568de5f052664f0a.html

The forced transformation of C-style is as follows:

(T) exdivssion // cast exdivssion to be of type T

Function-style forces the transformation to use the following syntax:

T (exdivssion) // cast exdivssion to be of type T

There is no essential difference between the two forms. It is simply a question of where brackets are placed. I call these two forms the forced transformation of old-style.

Use the Standard C ++ type conversion characters static_cast, dynamic_cast, reinterdivt_cast, and const_cast.

3.1 static_cast

Usage: static_cast <type-ID> (exdivssion)

This operator converts exdivssion to the Type-ID type, but there is no runtime type check to ensure the conversion security. It has the following usage:

① It is used to convert pointers or references between classes and subclasses in the class hierarchy.

It is safe to perform upstream conversion (converting the pointer or reference of a subclass to a base class;

When performing a downstream conversion (converting a base class pointer or reference to a subclass), it is not safe because there is no dynamic type check.

② It is used for conversion between basic data types. For example, convert int to Char and convert int to enum. The security of such conversions must also be ensured by developers.

③ Convert a null pointer to a null pointer of the target type.

④ Convert any type of expression to void type.

When applying multi-state programming, dynamic_cast is used when the actual type of the uploaded object cannot be determined. If the actual type of the object can be guaranteed, static_cast is used. As for reinterpret_cast, I like it very much. It is like the violent conversion in C Language :)

Dynamic_cast: dynamic type conversion
Static_cast: static type conversion
Reinterpret_cast: Reinterpreting type conversion
Const_cast: constant type conversion
I have learned a lot about my major. Let me talk about my own understanding:
Synamic_cast is generally used to convert the parent class and subclass pointers or applications;
Static_cast is generally a common data type (for example, int M = static_cast <int> (3.14 ));
Reinterpret_cast is similar to C in general type conversion operations.
Const_cast removes the cosnt or volatile attribute.

Note: static_cast cannot convert the const, volitale, or _ unaligned attributes of exdivssion.

3.2 dynamic_cast

Usage: dynamic_cast <type-ID> (exdivssion)

This operator converts exdivssion to an object of the Type-ID type. Type-ID must be a class pointer, class reference, or void *;

If type-ID is a class pointer type, exdivssion must also be a pointer. If type-ID is a reference, exdivssion must also be a reference.

Dynamic_cast is mainly used for upstream and downstream conversions between classes, and can also be used for cross conversions between classes.

When performing upstream conversion between classes, dynamic_cast and static_cast have the same effect;

Dynamic_cast provides the type check function for downstream conversions, which is safer than static_cast.

Class B {

Public:

Int m_inum;

Virtual void Foo ();

};

Class D: Public B {

Public:

Char * m_szname [100];

};

Void func (B * pb ){

D * pd1 = static_cast (PB );

D * Pd2 = dynamic_cast (PB );

}

In the above Code segment, if PB points to a D-type object, pd1 and Pd2 are the same, and it is safe to execute D-type operations on these two pointers;

However, if PB points to a B-type object, pd1 will be a pointer to this object, it is not safe to perform operations of the D type (for example, to access m_szname ),

Pd2 is a null pointer.

Note: B must have virtual functions; otherwise, compilation errors may occur. static_cast does not have this restriction.

This is because the runtime type check requires runtime type information, which is stored in the virtual function table of the class (

For more information about the concept of virtual function tables, see). Only classes that define virtual functions have virtual function tables,

Classes that do not define virtual functions do not have virtual function tables.

In addition, dynamic_cast also supports cross cast ). The following code is used.

Class {

Public:

Int m_inum;

Virtual void F (){}

};

Class B: Public {

};

Class D: Public {

};

Void Foo (){

B * pb = new B;

Pb-> m_inum = 100;

D * pd1 = static_cast (PB); // compile Error

D * Pd2 = dynamic_cast (PB); // Pd2 is null

Delete Pb;

}

In function Foo, using static_cast for conversion is not allowed, and errors will occur during compilation. Using dynamic_cast for conversion is allowed, and the result is a null pointer.

3.3 reinterpret_cast

Usage: reinterpret_cast (exdivssion)

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 (first, convert a pointer to an integer,

You can also obtain the original pointer value after converting the integer to the original type ).

This operator is used in many ways.

3.4 const_cast

Usage: const_cast (exdivssion)

This operator is used to modify the const or volatile attributes of the type. Apart from the const or volatile modifier, The type_id and exdivssion types are the same.

Constant pointers are converted to non-constant pointers and still point to the original object;

Constant reference is converted to a non-constant reference and still points to the original object. Constant object is converted to a non-constant object.

Voiatile and const classes. Take the following example:

Class B {

Public:

Int m_inum;

}

Void Foo (){

Const B B1;

B1.m _ inum = 100; // comile Error

B b2 = const_cast (B1 );

B2. m_inum = 200; // fine

}

The above code will report an error during compilation, because B1 is a constant object and cannot be changed;

Using const_cast to convert it into a constant object, you can change its data members at will. Note: B1 and B2 are two different objects.

========================================================== =====

= Dynamic_cast. vs. static_cast

========================================================== =====

Class B {...};

Class D: Public B {...};

Void F (B * pb)

{

D * pd1 = dynamic_cast (PB );

D * Pd2 = static_cast (PB );

}

If PB really points to an object of Type D, then pd1 and Pd2 will get the same value. They will also get the same value if PB = 0.

If Pb points to an object of type B and not to the complete D class, then dynamic_cast will know enough to return zero. however, static_cast relies on the programmer's assertion that Pb points to an object
Of type D and simply returns a pointer to that supposed D object.

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 is less efficient than static_cast in execution, but static_cast can complete ing in a wider range. This unrestricted ing is always insecure. In addition to static navigation at the class level, the transformation types covered by static_cast also include non- ing transformations and narrow transformations (such transformations can cause object slicing and information loss), forced conversion with void *, implicit type conversion, etc...

========================================================== =====

= Static_cast. vs. reinterpret_cast

========================================================== ============

Reinterpret_cast is used to map to a completely different type. This keyword is used when we need to map the type back to the original type. The type we map to is only for xuanjicang and other purposes, which is the most dangerous of all mappings. (This sentence is the original statement in C ++ programming ideas)

The static_cast and reinterpret_cast operators modify the operand type. They are not reciprocal. static_cast performs conversions using type information during compilation, and performs necessary checks during conversions (such as cross-border pointer calculation and type check). Its operations are relatively safe. On the other hand, reinterpret_cast only reinterprets the BIT model of the given object without binary conversion. The example is as follows:

Int n = 9; double D = static_cast <double> (N );

In the above example, we convert a variable from int to double. These types of binary expressions are different. To convert an integer 9 to a double-precision integer 9, static_cast needs to complement the bit with a double-precision integer d correctly. The result is 9.0. The reinterpret_cast behavior is different:

Int n = 9;

Double D = reinterpret_cast (N );

This time, the results are different. After calculation, D contains useless values. This is because reinterpret_cast only copies N bits to D and does not perform necessary analysis.

Therefore, use reinterpret_cast with caution.

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.