Differences between four types of forced type conversions in C + +

Source: Internet
Author: User

Use standard C + + type conversions: static_cast, dynamic_cast, reinterpret_cast, and const_cast.
1, static_cast
Usage:static_cast<type_id> (expression)
The operator converts expression to the 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:
(1) Conversions for pointers or references between base classes and derived classes in a class hierarchy
It is safe to make an upstream conversion (a pointer or reference to a derived class is converted to a base class representation)
A downstream conversion (a pointer or reference to a base class is represented by a derived class), which is unsafe because there is no dynamic type checking
(2) Used for conversions between basic data types, such as converting an int to char. The security of this conversion also needs to be developed to ensure
(3) Convert null pointer to null pointer of target type
(4) Convert any type of expression to void type
Note: static_cast cannot convert the const, Volitale, or __unaligned properties of expression.

2, dynamic_cast
Usage:dynamic_cast<type_id> (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 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.
The dynamic_cast is primarily used for upstream and downstream conversions between class hierarchies, and can also be used for cross-conversion between classes.
The effect of dynamic_cast and static_cast is the same when the upstream conversion is performed between class hierarchies;
In the downstream conversion, dynamic_cast has the function of type checking, which is more secure than static_cast.

    1. class b
    2. {
    3. public:
    4.     &NBSP;&NB Sp;int m_inum;
    5.        virtual void foo ();
    6. };
    7. class d:public b
    8. {
    9.     public:
    10.    &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;CHAR&NBSP;*M_SZNAME[100];
    11. };
    12. void func (B&NBSP;*PB)
    13. {
    14.     d *pd1 = static_ Cast<d *> (PB);
    15.     D *pd2 = dynamic_cast<D *> (pb);
    16. }

In the preceding code snippet, if PB points to an object of type D, PD1 and PD2 are the same, and any operation that performs type D on both pointers is safe;
However, if PB is pointing to an object of type B, then PD1 will be a pointer to that object, and the type D operation will be unsafe (such as access M_szname).
And PD2 will be a null pointer.
Also note: B to have virtual function, or compile error, static_cast There is no such limit.
This is because runtime type checking requires run-time type information, and this information is stored in the class's Virtual function table (
With regard to the concept of virtual function tables, in detail <inside C + + object model>, only classes that define virtual functions have virtual function tables.
A class that does not have a virtual function defined is not a virtual function table.

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

  1. Class A
  2. {
  3. Public
  4. int m_inum;
  5. virtual void F () {}
  6. };
  7. Class B:public A
  8. {
  9. };
  10. Class D:public A
  11. {
  12. };
  13. void Foo ()
  14. {
  15. b *PB = new B;
  16. Pb->m_inum = 100;
  17. D *PD1 = Static_cast<d *> (pb); Compile error
  18. D *pd2 = Dynamic_cast<d *> (pb); PD2 is NULL
  19. Delete PB;
  20. }

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

3, 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 convert an integer to a pointer (convert a pointer to an integer,
     The original pointer value can also be obtained when the integer is converted to a pointer of the original type.
     the operator uses more.
     (static_cast. vs. reinterpret_cast, see below)
    The operator platform portability comparison.

4, const_cast
    usage:const_cast<type_id> (expression)
      This operator is used to modify the const or volatile properties of a type. In addition to const or volatile adornments, the type_id and expression types are the same. The
     constant pointer is converted to a very pointer, and still points to the original object;
     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.
    Volatile and const types, as shown in the example below.

    1. Class B
    2. {
    3. Public
    4. int m_inum;
    5. }
    6. void Foo ()
    7. {
    8. Const B B1;
    9. B1.m_inum = 100; Comile Error
    10. B B2 = const_cast<b> (B1);
    11. B2. M_inum = 200; Fine
    12. }

The above code compiles with an error, because B1 is a constant object and cannot be changed;
By using const_cast to convert it to a very mass object, it can arbitrarily change its data members. Note: B1 and B2 are two different objects.

5. Comparison
(1) dynamic_cast vs static_cast

    1. Class B
    2. {
    3. ...
    4. };
    5. Class D:public B
    6. {
    7. ...
    8. };
    9. void F (b* pb)
    10. {
    11. d* PD1 = dynamic_cast<d*> (PB);
    12. d* PD2 = static_cast<d*> (PB);
    13. }

If PB really points to a object of type D, then PD1 and PD2 would get the same value. They would also get the same value if PB = = 0.
If PB points to a object of 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 that 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 a downward transformation in the inheritance system, converting a base-class pointer to a derived class pointer, which is stricter and more secure than static_cast. The dynamic_cast is less efficient than static_cast, but the static_cast can be mapped in a wider range, and this unrestricted mapping is accompanied by insecurity. In addition to the static navigation of the class hierarchy, the transformation types covered by static_cast include no-mapping transformations, narrow transformations (which can result in object slicing, loss of information), forced transformations with void*, implicit type transformations, etc.

(2) static_cast vs reinterpret_cast
Reinterpret_cast is meant 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 type we map to is just for the sake of the trick and other purposes, which is the most dangerous of all mappings. (This is the exact words in C + + programming Idea)
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 checks on transformations (such as pointer out-of-bounds calculations, type checking). The operands are relatively safe. Reinterpret_cast, on the other hand, simply re-interprets the given object's bit model without binary conversion, as in the following example:

    1. int n=9; Double D=static_cast < double > (n);

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

    1. int n=9;
    2. Double d=reinterpret_cast<double & > (n);

This time, the results are different. After the calculation, D contains a useless value. This is because reinterpret_cast only replicates n bits to D and does not perform the necessary analysis.
Therefore, you need to be cautious about using reinterpret_cast.

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

Add:
(1) Static_cast: Functionally basically as powerful as the C-style type conversion, meaning is the same. It has a functional limit. For example, you cannot 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 conversion character const_cast has such a function.
 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: const or volatile attribute used for type conversion off expression. By using const_cast, you emphasize to people and compilers that what you want to do with a type conversion is just a constness or volatieness property that changes something. This meaning is constrained by the compiler. If you try to use const_cast to finish modifying things other than 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 a class. That is, you can use dynamic_cast pointer or reference to the base class to convert exponentially to its derived class or its sibling class, and you can know 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 results are almost all of the execution period definition. Therefore, code that uses reinterpret_cast is difficult to port. The most common use of reinterpret_casts is to convert between function pointer types.
Examples are as follows:

  1. #include <iostream>
  2. using namespace Std;
  3. Class A
  4. {
  5. Public
  6. virtual void foo ()
  7. {
  8. }
  9. };
  10. Class B
  11. {
  12. Public
  13. virtual void foo ()
  14. {
  15. }
  16. };
  17. Class C:public A, public B
  18. {
  19. Public
  20. virtual void foo () {}
  21. };
  22. void Bar1 (A *pa)
  23. {
  24. B *pc = dynamic_cast<b*> (PA);
  25. }
  26. void Bar2 (A *pa)
  27. {
  28. B *pc = static_cast<b*> (PA); Error
  29. }
  30. void Bar3 ()
  31. {
  32. c C;
  33. A *pa = &c;
  34. B *PB = static_cast<b*> (static_cast<c*> (PA));
  35. }
  36. int main ()
  37. {
  38. return 0;
  39. }

A, BAR1 cannot be compiled
B. BAR2 cannot be compiled
C, BAR3 cannot be compiled
D, BAR1 can operate normally, but the wrong cast method is used
Answer:
Select B.
Dynamic_cast is traversing 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, it's wrong to run the Times (so both A and d are wrong).
Static_cast: Any type conversions that the compiler implicitly executes can be displayed by it. Where 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, an error occurs (so B is correct), and if there is an inheritance relationship, you can make any transformation between the base class and the derived class, without errors during compilation. So BAR3 can be compiled (the C option is wrong).

This article was transferred from: http://blog.chinaunix.net/uid-26548237-id-3954104.html

Differences between four types of forced type conversions in C + +

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.