C + + type conversion operator

Posted by iZone on Sun, 09 Jan 2022 13:47:03 +0100

keywordexplain
static_cast It is used for benign conversion. Generally, it will not lead to accidents and the risk is very low.
const_cast Used for conversion between const and non const, volatile and non volatile.
reinterpret_cast Highly dangerous conversion. This conversion is only a reinterpretation of binary bits. It is static_ Complementarity of cast
dynamic_cast With RTTI, it is used for type safe downlink conversion. Uplink conversion and static_ Like cast.

 

static_cast keyword

This operator can perform benign type conversion with low conversion risk. It is mainly used for the following purposes:
① used for pointer or reference conversion between base class (parent class) and derived class (child class).
It is safe to perform uplink conversion (convert the pointer or reference of the derived class to the representation of the base class);
When performing a downstream conversion (converting a base class pointer or reference to a derived class representation), it is unsafe because there is no dynamic type checking.
② it is used for conversion between basic data types, such as short to int, int to double, int to char, etc. the security of this conversion should also be guaranteed by developers.
③ convert the null pointer to the null pointer of the target type, such as void * to int *.
④ convert any type of expression to void type, such as int to void.
⑤ const, volatile__ unaligned attribute

static_cast has no type check to ensure the security of conversion. It cannot be used for conversion between unrelated types, for example:

  • Conversion between two specific type pointers, such as int * to double *, Student * to int *. Different types of data have different storage formats and lengths. After the pointer of type a points to the data of type B, the data will be processed in the way of type A: if it is a read operation, a pile of meaningless values may be obtained; If it is a write operation, type B data may be destroyed; When the data is read in type B again, a pile of meaningless values will be obtained.
  • Conversion between int and pointer. Assigning a specific address to a pointer variable is very dangerous because the memory on that address may not be allocated or may not have read and write permissions.

static_cast is converted during compilation. If the conversion fails, a compilation error will be thrown.

    int m = 100;long n = static_cast<long>(m);  //Wide conversion, no information loss
    char ch = static_cast<char>(m);  //Narrow conversion, information may be lost
    int *p1 = static_cast<int*>(malloc(10 * sizeof(int)));  //take void Convert pointer to concrete type pointer
    void *p2 = static_cast<void*>(p1);  //Convert a specific type pointer to void Pointer
   
    //The following usage is wrong
    float *p3 = static_cast<float*>(p1);  //Cannot convert between pointers of two concrete types
    p3 = static_cast<float*>(0X2DF9);  //Cannot convert an integer to a pointer type

 

const_cast keyword

 const_cast is used to convert const/volatile type to non const/volatile type.

    const int n = 100;
    int *p = const_cast<int*>(&n);
    *p = 234;
    cout << " n = " << n << endl; //100
    cout << " *p = " << *p << endl; //234

&n is used to obtain the address of n. its type is const int *. Const must be used_ Cast can be assigned to p only after it is converted to int * type. Because p points to n, and n occupies stack memory and has write permission, you can modify the value of n through p.

Because the constant processing in C + + is more like #define during compilation, it is a process of value replacement. All places using n in the code are replaced with 100 during compilation. In other words, line 4 has been modified to the following form:

    cout << " n = " << 100 << endl; //100

 

reinterpret_cast keyword

reinterpret_cast only reinterprets the binary bits and does not adjust the data with the help of the existing conversion rules.

reinterpret_cast can be considered as static_ A supplement to cast, some static_ If cast cannot complete the conversion, you can use {reinterpret_cast, such as the conversion between two concrete type pointers, int and pointer.

    //take char* Convert to float*
    char str[] = "http://c.biancheng.net";
    float *p1 = reinterpret_cast<float*>(str);
    cout << *p1 << endl; //3.0262e+29

    //take int Convert to int*
    int *p = reinterpret_cast<int*>(100);
    cout << *p << endl; //100

 

dynamic_cast keyword

dynamic_cast is used for type conversion between inheritance levels of classes. It allows both uplink and downlink conversion.

  • Uplink conversion is unconditional. As long as there is an inheritance relationship between the two types to be converted and the base class contains virtual functions (these information can be determined during compilation), no detection will be carried out and it will succeed.
  • The premise of downlink conversion must be safe. Only part of all can succeed with the help of RTTI.
  • dynamic_cast can only convert pointer - > pointer or reference - > reference. For pointers, NULL will be returned if conversion fails; For references, STD:: base will be thrown if the conversion fails_ Cast exception.

dynamic_cast and static_cast is relative. dynamic_cast will carry out type conversion with RTTI during program running, which requires that the base class must contain virtual functions; static_cast completes type conversion during compilation, which can find errors more timely.

//Downlink conversion

class A {
public:
    virtual void func() const { cout<<"Class A"<<endl; }
private:
    int m_a;
};

class B : public A {
public:
    virtual void func() const { cout<<"Class B"<<endl; }
private:
    int m_b;
};

class C : public B {
public:
    virtual void func() const { cout<<"Class C"<<endl; }
private:
    int m_c;
};

class D : public C {
public:
    virtual void func() const { cout<<"Class D"<<endl; }
private:
    int m_d;
};

int main(){
    A *pa = new A();
    B *pb;
    C *pc;
   
    //situation①
    pb = dynamic_cast<B*>(pa);  //Downward transformation failed
    pc = dynamic_cast<C*>(pa);  //Downward transformation failed
   
    //situation②
    pa = new D();  //Upward transformation is allowed
    pb = dynamic_cast<B*>(pa);  //Successful downward transformation
    pc = dynamic_cast<C*>(pa);  //Successful downward transformation

    return 0;
}

 

Topics: C++