C ++ type conversion (translated from cplusplus)

Source: Internet
Author: User
Preface

Original translated from simplified.

In C ++, convert a known type to another type. We call it type conversion. This article will introduce various types of conversion in C ++.

Implicit conversion

Implicit conversion does not require any operators. They are automatically executed and values are assigned to compatible types. For example:

short a=2000;
int b;
b=a;

Implicit conversions include constructor and operator conversion, for example:

class A {};
class B { public: B (A a) {} };

A a;
B b=a;

 

Explicit Conversion

C ++ is a strongly typed language. Many conversions require Explicit conversions, such

short a=2000;
int b;
b = (int) a; // c-like cast notation
b = int (a); // functional notation

 

The above type conversion satisfies the basic type conversion. However, if it is applied to classes and pointers, the code can be compiled, but errors may occur during the running process. For example

// class type-casting
#include <iostream>
using namespace std;

class CDummy {
float i,j;
};

class CAddition {
int x,y;
public:
CAddition (int a, int b) { x=a; y=b; }
int result() { return x+y;}
};

int main () {
CDummy d;
CAddition * padd;
padd = (CAddition*) &d;
cout << padd->result();
return 0;
}

This code will cause an error at runtime and exit unexpectedly when padd-> result () is executed.

Conventional explicit type conversion can be converted to any other pointer type, and any pointer pointing to the type is irrelevant. A running error or unexpected result will be generated in the subsequent call Member results.

 

C ++ standard conversion Operator

Traditional type conversion of classes and pointers is very insecure and may exit during runtime due to Type Mismatch exceptions. Therefore, C ++ provides four standard conversion operators: dynamic_cast, reinterpret_cast, static_cast, const_cast

dynamic_cast <new_type> (expression)
reinterpret_cast <new_type> (expression)
static_cast <new_type> (expression)
const_cast <new_type> (expression)

 

Dynamic_cast

Dynamic_cast can only be used for pointers and referenced objects. The purpose is to ensure that the type conversion result is an object that effectively completes the requested class, so when we convert from a class to the base class of this class, dynamic_cast will always succeed.

class CBase { };
class CDerived: public CBase { };

CBase b; CBase* pb;
CDerived d; CDerived* pd;

pb = dynamic_cast<CBase*>(&d); // ok: derived-to-base
pd = dynamic_cast<CDerived*>(&b); // wrong: base-to-derived

If the new type is not the base class of the converted type and dynamic_cast cannot complete pointer conversion, NULL is returned. If dynamic_cast is used for conversion to the reference type, "Bad_cast exception" is thrown.

Dynamic_cast can convert NULL pointers to unrelated classes or void pointers of any type.

The runtime type information (RTTI) required by dynamic_cast to maintain dynamic type tracking. Some compilers support this feature as disabled by default. This must enable the runtime type check and use dynamic_cast to work properly.

 

Static_cast

Static_cast can be used to convert pointers of related classes, not only from the derived class to the base class, but also from the base class to the derived class. Static_cast does not perform a security check at runtime. Therefore, it is a programmer to ensure that the conversion is safe, but static_cast can avoid the overhead of the dynamic_cast type security check.

class CBase {};
class CDerived: public CBase {};
CBase * a = new CBase;
CDerived * b = static_cast<CDerived*>(a);

 

The above code is legal, although B points to an incomplete object and may cause errors at runtime.

Static_cast can also be used to execute any other non-pointer conversions, such as standard conversions between basic types, or implicitly

double d=3.14159265;
int i = static_cast<int>(d);

 

Reinterpret_cast

Reinterpret_cast is converted to any other pointer type, or even unrelated class, any pointer type. The result of the operation is a simple binary copy from a pointer to other values. All pointer conversions are allowed: whether the Pointer Points to the content or the type of the pointer itself.

At the same time, it can also convert the pointer to an integer, but the integer is platform-related, must ensure that the integer is large enough to include the content of the pointer itself, and finally convert it to a valid pointer.

class A {};
class B {};
A * a = new A;
B * b = reinterpret_cast<B*>(a)

 

Const_cast

Const_cast is used to manipulate the object's constants. It must be set or deleted. For example, a function requires a non-const parameter, and the program needs to pass a const parameter.

#include <iostream>
using namespace std;

void print (char * str)
{
cout << str << endl;
}

int main () {
const char * c = "sample text";
print ( const_cast<char *> (c) );
return 0;
}

 

Typeid

Type of the expression that can be checked for typeid
Typeid (expression)

 

This operator returns a constant object referenced in the standard header file <typeinfo>, which is a type of type_info. This return value can be equivalent to another operator ==and! = Compare the names of two data types or classes, or use its name () member function to obtain the type name (a string ended with 0 ).

// typeid
#include <iostream>
#include <typeinfo>
using namespace std;

int main () {
int * a,b;
a=0; b=0;
if (typeid(a) != typeid(b))
{
cout << "a and b are of different types:\n";
cout << "a is: " << typeid(a).name() << '\n';
cout << "b is: " << typeid(b).name() << '\n';
}
return 0;
}

When the typeid application uses RTTI to track the types of dynamic objects, when typeid is applied to expressions, its type is A polymorphism class, and the result is the type of the derived most complete object:

// typeid, polymorphic class
#include <iostream>
#include <typeinfo>
#include <exception>
using namespace std;

class CBase { virtual void f(){} };
class CDerived : public CBase {};

int main () {
try {
CBase* a = new CBase;
CBase* b = new CDerived;
cout << "a is: " << typeid(a).name() << '\n';
cout << "b is: " << typeid(b).name() << '\n';
cout << "*a is: " << typeid(*a).name() << '\n';
cout << "*b is: " << typeid(*b).name() << '\n';
} catch (exception& e) { cout << "Exception: " << e.what() << endl; }
return 0;
}

Note: The type_info name of the returned string Member depends on the implementation of your compiler and library. Its typical type name is not necessarily a simple string.

If the typeid parameter is a pointer starting with the reference operator (*) and the pointer is NULL, typeid throws a bad_typeid exception.

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.