C++ explicit type conversion example

  • 2020-04-02 02:14:30
  • OfStack

Standard C++ contains an explicit conversion syntax:

Static_cast: for "benign" and "moderately benign" conversions, including non-cast conversions

Const_cast: used for "const" and/or "volatile" conversions

Reinterpret_cast: converts to a completely different meaning. In order to use it safely, the key must be converted back to the original type. The converted type can only be used for bitwise operations, otherwise it is used for other covert purposes. This is the most dangerous of all transitions.

Dynamic_cast: for type safe downcast

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

Static_cast: for all explicitly defined transformations, including casts of void*, implicit type conversions, and static positioning at the class level.

1. Conversion of data types from small to large, such as int to long or float;


int i ; static_cast<long>(i); static_cast<float>(i);

2. Narrow conversion, that is, the conversion of data type from large to small, may lose data;

3. In c++, it is not allowed to assign values to data of type void*;


void* ptr;  ptr = static_cast<void*>(i);


Const_cast: constant conversion. You can use const_cast if you are converting from const to non-const or from volatile to non-volatile. This is the only transformation const_cast allows.

volatile int k = 0;   int* u = const_cast<int*>(&k);


Four explicit type conversions use the example

1, reinterpret_cast
The type conversion function converts a pointer of one type to a pointer of another type. This conversion does not require changing the format of the data store for pointer variable values, but simply recompiling the type of the interpreted pointer at compile time.


double d=9.3;
double *pd=&d;
int *pi=reinterpret_cast<int*>(pd);

It cannot be used for non-pointer type conversions.
As with implicit conversions, reinterpret_cast cannot convert a const pointer to a void* pointer.

2, const_cast
Used to remove the constant property of a pointer variable and convert it to a normal variable of the corresponding pointer type. You can also convert a nontrivial pointer variable to a constant pointer variable and make type changes during compilation.


const int* pci=0;
int* pj=const_cast<int*>(pci);

For security reasons, const_cast cannot convert nonpointer constant variables to normal variables.
You can convert ordinary pointer variable PI to regular pointer variable, but you cannot convert non-pointer ordinary variable to regular variable.

3, static_cast
Used for conversions between primitive types and between types with inheritance relationships, which typically change the internal representation of a variable. Used for pointer type conversion, not much sense.


class Base();
class Derived:public Base{}
Derived d;
Base d=static_cast<Base>(d);

An inherited class object can be converted to a base class object. But not the other way around.
Note: base class pointer conversion to inherited class pointer, in a certain degree of harm.

4, dynamic_cast
As opposed to static_cast, there is a dynamic dynamic_cast transformation. This transformation is analyzed at run time, not at compile time. You can cast only between Pointers or references to inherited class objects. When converting, the current (RTTI) is used to determine whether the conversion between type objects is legal. Dynamic_cast conversion failed, is detected by whether it is a null pointer; The reference conversion failed, throwing a bad_cast exception.
Converting inherited class Pointers or references to base class Pointers or references works, but not the other way around. But if there are virtual functions in the base class, that is, if the converted class has an object pointer to the virtual function, the compilation passes.


class Base();
class Derived:public Base{}
Derived *pd=new Derived;
Base *d=dynamic_cast<Base*>(pd);

In addition, if there is no inheritance, but the converted class has an object pointer to a virtual function, the transformation can be compiled.

int i;
long m;
m=static_cast<long>(i);
const int i=0;
int* j=(int*)&i;
j=const_cast<int*>(&i);//Converts const type to volatile.


#include "iostream"
using namespace std;
const int sz=100;
struct X 
{
int a[sz];
};
void print(X* x)
{
for(int i=0;i<sz;i++)
cout<<x->a[i]<<' ';
cout<<endl<<"------------"<<endl;
}
int main()
{
X x;
print(&x);
int* xp=reinterpret_cast<int*>(&x);//cast &x to int*
for(int* i=xp;i<xp+sz;i++)
*i=0;
//cannot use xp as an X* at this point usless you cast it bakc;
print(reinterpret_cast<X*>(xp));
print(&x);
return 1;
}


Related articles: