People who have studied C + + know that C + + is a strongly typed language, so variables must declare data types before they are used, and the amount of memory space allocated by different data types is different, especially when converting types to prevent data loss or transboundary overflow. This article will summarize the C + + type conversion in detail.
C + + has developed in the form of both C-style conversions: implicit conversions and explicit conversions .
1. Implicit conversions
Implicit conversions are type conversions that are performed automatically by the compilation system and do not require human intervention, such as:
Implicit conversions, which also include conversions of constructors and operators, for example:
Class A {};
Class B {public
:
B (a) {}
};
A A;
b b = A;
2. Explicit conversion
In contrast to an implicit conversion, an explicit conversion takes advantage of the coercion type conversion operator, for example:
Double x = 10.3;
int y;
y = int (x); function type
y = (int) x; C-style wording
The above type conversions have already satisfied the basic type of conversion. But if you want to convert classes and pointers, sometimes the code can compile and there will be errors during the run. For example:
#include <iostream>
class Cdummy {
float i,j;
Public:
Cdummy () {i=1; j=1;}
};
Class Caddition {
int x,y;
Public:
caddition () {x=1; y=1;}
int result () {return x+y;}
};
int main () {
cdummy D;
Caddition * PADD;
Padd = (caddition*) &d;
Std::cout << Padd->result ();
return 0;
}
This code has an error at runtime, an exception occurs while executing Padd->result (), and some compilers exit unexpectedly.
Traditional explicit type conversions can be converted to any pointer of any other pointer type, regardless of the type they point to. The result of a subsequent call member results in a run-time error or unexpected result.
C + + standard conversion operators
Traditional class and pointer type conversions are unsafe and may exit abnormally at run time, and standard C + + provides four 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)
1.dynamic_cast
dynamic_cast can only be used for pointers and referenced objects. The goal is to ensure that the result of the type conversion is a valid object to complete the requested class, so when we convert from a class to the parent class of the class, dynamic_cast always succeeds . Dynamic_cast can convert null pointers to unrelated classes, or any type of pointer to a void pointer.
Class CBase {};
Class Cderived:public CBase {};
CBase b;
CDerived D;
cbase* PB = dynamic_cast<cbase*> (&d); Subclass to Parent class, correct
//cderived* PD = dynamic_cast<cderived*> (&B);//parent Class rotor class, error
when the new type is not a parent of the converted type, dynamic_cast cannot complete the conversion of the pointer and returns null. when dynamic_cast converts a reference type, a Bad_cast exception is thrown when a failure is encountered .
2.static_cast
static_cast can perform conversions between the pointers of related classes, which can be converted between subclasses and parent classes, but it is not safe for the parent class pointer to be turned into a subclass pointer. static_cast does not perform security checks at run time, so we have to make sure that the conversion is safe first. On the other hand, static_cast contrast dynamic_cast less overhead in type security checks.
Class CBase {};
Class Cderived:public CBase {};
CBase * a = new CBase;
CDerived * b = static_cast<cderived*> (a);
The above code is legal, and b points to an incomplete object, which may cause an error during the run time.
static_cast can also be used to perform any other non pointer conversions, such as the standard conversions between the basic type enum, struct, int, char, float , and so on:
Double d = 3.14159265;
int i = static_cast<int> (d);
void* p = static_cast<void*> (&i); Convert any type to void type
3.reinterpret_cast
reinterpret_cast is converted into any other pointer type, even unrelated to the class, any pointer type. The result of the operation is to redefine the type, but there is no binary conversion. All pointer conversions are allowed: whether the pointer is pointing to something or the type of the pointer itself.
Class A {};
Class B {};
A * a = new A;
b * b = reinterpret_cast<b*> (a)
Reinterpret_cast can also be used to convert function pointer types, such as:
typedef void (*FUNC) (); Declares a function pointer definition that returns the void
Func Pfunc; Defines an array of funcptr types
//pfunc = &test; Compile Error! Type mismatch
Pfunc = reinterpret_cast<func> (&test);//Compilation Successful! Convert function pointer type
4.const_cast
const_cast is used to manipulate the constants of objects and to remove the const or volatile attributes of the type .
#include <iostream>
void print (char * str) {
std::cout << str;
}
int main () {
const char* c = "Hello World";
Print (Const_cast<char *> (c));
return 0;
}