Type conversions in C + + static_cast, dynamic_cast, const_cast, and reinterpret_cast summary _c language

Source: Internet
Author: User
Tags volatile

Objective

This article summarizes the type conversion in C + +, these small knowledge points, sometimes, they are not very attention, but in actual development is often used. As the saying goes, a programmer who does not understand the code he writes is not a good programmer; If a programmer does not understand the code they write, just know what to use, and one day you will lose your own.

Type conversions in C + + are divided into two categories:

1. implicit type conversion;
2. Explicit type conversions.

For implicit transformations, which are standard conversions, which occur inadvertently in many cases, such as int and float, the int type is implicitly converted to the bit float type and then added. Implicit conversions are not the focus of today's summary, but the emphasis is on explicit conversions. There are four types of conversion characters in standard C + +: static_cast, dynamic_cast, Const_cast, and reinterpret_cast, which are summarized in one by one below.

Static_cast

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

Converts expression to Type-id types, primarily for conversions between non polymorphic types, and does not provide run-time checks to ensure the security of conversions. Mainly used in the following situations:

1. For use in class hierarchies, the conversion of pointers and references between base classes and subclasses;
This conversion is safe when an upward conversion, i.e. a pointer or a reference to the handle class, is converted into a parent class;
When the downlink conversion, that is, the parent class pointer or reference to the subclass of the conversion is not secure, but also need the programmer to ensure;

2. For conversion between basic data types, such as converting int to char, converting int to enum, and so on, the security of this conversion needs to be guaranteed by the programmer;

3. Converts a void pointer to a pointer of the target type and is not safe;

Note: static_cast cannot convert the const, volatile, and __unaligned properties of expression.

dynamic_cast

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

Converts a expression to a Type-id type, Type-id must be a pointer to a class, a reference to a class, or a void *; if Type-id is a pointer type, then expression must also be a pointer; 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, and the dynamic_cast has the function of type checking, which is more secure than static_cast in the downlink conversion. Conversions between polymorphic types primarily use dynamic_cast, because the type provides run-time information. Below I will be in the following several occasions for the use of dynamic_cast summary:

1. The simplest uplink conversion

For example, b inherits from A,b to a and is safe for uplink conversion, as follows:

Copy Code code as follows:

#include <iostream>
using namespace Std;
Class A
{
// ......
};
Class B:public A
{
// ......
};
int main ()
{
b *PB = new B;
A *pa = Dynamic_cast<a *> (PB); Safe and would succeed
}

2. Upstream conversion between multiple inheritance

C inherits from the B,b inherited from a, this multiple inheritance relationship; However, the relationship is very clear, when using dynamic_cast for conversion, it is also very simple:

Copy Code code as follows:

Class A
{
// ......
};
Class B:public A
{
// ......
};
Class C:public B
{
// ......
};
int main ()
{
c *pc = new C;
B *PB = dynamic_cast<b *> (PC); Ok
A *pa = Dynamic_cast<a *> (PC); Ok
}

And the above conversion, static_cast and dynamic_cast have the same effect. This kind of upside down is also called implicit conversion, as we often write when we define variables: B *PB = new C; This is the same as the above, just adding a dynamic_cast converter.

3. Convert to void *

You can convert a class to void *, for example:

Copy Code code as follows:

Class A
{
Public
virtual void F () {}
// ......
};
Class B
{
Public
virtual void F () {}
// ......
};
int main ()
{
A *pa = new A;
b *PB = new B;
void *PV = Dynamic_cast<void *> (PA); PV points to A
PV = dynamic_cast<void *> (PB); PV points to a B
}

However, you must include virtual functions in Class A and Class B, why? Because a virtual function exists in a class, it means that it has a case where the base class pointer or reference is pointing to a derived class object, and the conversion makes sense, because Run-time type checking requires run-time type information, which is stored in the virtual function table of the class, and only the class that defines the virtual function has a virtual function table.

4. If expression is the base class for Type-id, when using dynamic_cast for conversion, the runtime checks to see if expression really points to a Type-id type of object, and if so, the correct conversion to get the corresponding value Otherwise, NULL is returned, and if it is a reference, an exception is thrown at run time, for example:

Copy Code code as follows:

Class B
{
virtual void F () {};
};
Class D:public B
{
virtual void F () {};
};
void Main ()
{
b* PB = new D; Unclear but OK
b* PB2 = new B;
d* PD = dynamic_cast<d*> (PB); OK:PB actually points to a D
d* pd2 = dynamic_cast<d*> (PB2); PB2 points to a B isn't a D, now PD2 is NULL
}

This is the downlink transformation, from the base class pointer to the derived class pointer.
For some complex inheritance relationships, there are pitfalls in using dynamic_cast for conversion; For example, a structure like this:

The D type can be safely converted to type B and C, but the D type is directly convertible to type a?

Copy Code code as follows:

Class A
{
virtual void Func () = 0;
};
Class B:public A
{
void Func () {};
};
Class C:public A
{
void Func () {};
};
Class D:public B, public C
{
void Func () {}
};
int main ()
{
D *pd = new D;
A *pa = Dynamic_cast<a *> (PD); You'll get a pA which is NULL
}

If you make a direct turn above, you will get a null PA pointer, because both B and C inherit a and all implement the virtual function func, which makes it impossible to decide which a to convert when making a transition. The correct approach is:

Copy Code code as follows:

int main ()
{
D *pd = new D;
B *PB = dynamic_cast<b *> (PD);
A *pa = Dynamic_cast<a *> (PB);
}

This is when I get the IUnknown pointer when I implement QueryInterface, I use *PPV = Static_cast<ix *> (this), not *PPV = Static_cast<iunknown * > (this);

For multiple inheritance situations, special attention is required when you turn from a derived class to the parent class of a parent class, such as the following:

Now, you have a pointer to the type a, which points to the E instance, how do you get a pointer to type B and point to the E instance? If the direct transfer, there will be compiler differences, do not know is to walk e->c->b, or walk e->d->b. In this case, we must first make a downward conversion of the pointer of type A, get a pointer of type E, and then convert the uplink in the specified correct route.

The above is a few details of the dynamic_cast conversion, especially for multiple inheritance, in the actual project, the problem is very easy to occur.

Const_cast

Const_cast conversion Format: const_cast <type-id> (expression)

Const_cast is used to remove the const, volatile, and __unaligned properties of a type. The constant pointer is converted to a very measured pointer, and still points to the original object, and the constant reference is converted to a very strong reference and still references the original object. Look at the following code example:

Copy Code code as follows:

/*
* * Filename:constcastdemo
* * author:jelly Young
* * DATE:2013/12/27
* * Description:more information, http://www.jb51.net
*/
#include <iostream>
using namespace Std;
Class CA
{
Public
CA (): M_ia (10) {}
int M_ia;
};
int main ()
{
Const CA *PA = new CA;
Pa->m_ia = 100; Error
CA *PB = Const_cast<ca *> (PA);
Pb->m_ia = 100;
Now the PA and the petabytes points to the same object
cout<<pa->m_ia<<endl;
cout<<pb->m_ia<<endl;
Const CA &a = *PA;
A.m_ia = 200; Error
CA &b = Const_cast<ca &> (a);
Pb->m_ia = 200;
Now the A and the B reference to the same object
cout<<b.m_ia<<endl;
cout<<a.m_ia<<endl;
}

Note: You cannot directly remove its const, volatile, and __unaligned properties by using the const_cast operator for both non-pointer and unreferenced variables.

Reinterpret_cast

Reinterpret_cast conversion Format: reinterpret_cast <type-id> (expression)

Allow any pointer type to be converted to another pointer type; it sounds powerful, but it's also very unreliable. It is primarily used to convert a data type from one type to another. It can convert a pointer to an integer, you can also convert an integer to a pointer, in actual development, first converts a pointer to an integer, in the conversion of the integer to the original type of the pointer, you can also get the original pointer value, especially open up the system's global memory space, need to be used between multiple applications , you need to share each other, pass the memory space of the pointer, you can convert the pointer to an integer value, and then convert the integer value to the pointer, the corresponding operation.

Summarize

This blog post summarizes the type conversions in C + +, focusing on the explicit conversions. The four explicit conversions supported by C + + are described in detail. If you have anything to add, or I summed up the wrong place, please give us a lot of advice.

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.