New Type Conversion (9)

        The type conversion we used in the C language was forced type conversion , which is very prone to bugs and difficult to find. The format is as follows: (Type)(Experssion) or Type(Experssion) , let's take a look at a sample code to see the type conversion in C language

#include <stdio.h>

typedef void(PF)(int);

struct Point
{
    int x;
    int y;
};

int main(int argc, char *argv[])
{
    int v = 0x12345;
    PF * pf = (PF *) v;
    char c = char(v);
    Point* p = (Point*)v;
    
    pf(5);
    
    printf("p->x = %d\n", p->x);
    printf("p->y = %d\n", p->y);
    
    return 0;
}

        The compilation result is as follows

picture.png

        We see a segfault when running directly, but it compiles fine, so it's hard to find bugs if we're in a large project.

        In the process of forced type conversion in C mode, it has problems: a> Too rough: conversion between any type can be performed, and it is difficult for the compiler to judge its correctness; b> Difficult to locate: it cannot be quickly located in the source code All statements that use casts . Then forced type conversion is difficult to completely avoid in actual engineering! How to perform a more secure and reliable conversion? In C++ there is a new type conversion, C++ divides the cast into 4 different types: a> static_cast; b> const_cast; c> dynamic_cast; d> reinterpret_cast ; usage is: xxx_cast<Type>(Expression) . Next, let's talk about the characteristics and requirements of these four new types of conversion.

        A, static_cast forced type conversion

        It is used for conversion between basic types; it cannot be used for conversion between basic type pointers; it is used for conversion between class objects with inheritance relationship and conversion between class pointers.

        B, const_cast forced type conversion

        Read-only attribute used to remove variables; the target type of the cast must be a pointer or reference.

        C. reinterpret_cast casts the type

        For casts between pointer types; for casts between integer and pointer types.

        D. dynamic_cast forced type conversion

        It is used for conversion between class pointers with inheritance relationship; it is used for conversion between class pointers with cross relationship; it has the function of type checking; it needs the support of virtual functions.

        Regarding some of the concepts mentioned above, we will introduce them in detail later. Let's analyze the code as an example.

#include <stdio.h>

void static_cast_demo()
{
    int i = 0x12345;
    char c = 'c';
    int* pi = &i;
    char* pc = &c;
    
    c = static_cast<char>(i);
    pc = static_cast<char*>(pi);    // error
}

void const_cast_demo()
{
    const int& j = 1;
    int& k = const_cast<int&>(j);
    
    const int x = 2;
    int& y = const_cast<int&>(x);
    
    int z = const_cast<int>(x);    // error
    
    k = 5;
    
    printf("k = %d\n", k);
    printf("j = %d\n", j);
    
    y = 8;
    
    printf("x = %d\n", x);
    printf("y = %d\n", y);
    printf("&x = %p\n", &x);
    printf("&y = %p\n", &y);
}

void reinterpret_cast_demo()
{
    int i = 0;
    char c = 'c';
    int* pi = &i;
    char* pc = &c;
    
    pc = reinterpret_cast<char*>(pi);
    pi = reinterpret_cast<int*>(pc);
    pi = reinterpret_cast<int*>(i);
    c = reinterpret_cast<char>(i);     // error
}

void dynamic_cast_demo()
{
    int i = 0;
    int* pi = &i;
    char* pc = dynamic_cast<char*>(pi);    // error
}

intmain()
{
    static_cast_demo();
    const_cast_demo();
    reinterpret_cast_demo();
    dynamic_cast_demo();
    
    return 0;
}

        Let's analyze this code. In static_cast_demo, static_cast cannot be used for conversion between pointers, so line 11 will report an error. In const_cast_demo, line 16 defines a variable j with read-only attribute, and we can still change its attribute through const_cast. Line 19 defines a real constant that goes into the symbol table, but allocates 4 bytes of space for it on the stack, so line 20 will also succeed. The target type of the const_cast cast must be a pointer or reference, so line 22 will report an error. Lines 26 and 27 will print 5 and 5; lines 31-34 will print 2, 8, and the last two addresses are the same. In reinterpret_cast_demo, reinterpret_cast is used for coercion between pointer types and between integer and pointer types, so line 47 will report an error. In dynamic_cast_demo, line 54 throws an error. Let's take a look at the compilation results

picture.png

        Let's comment out these lines separately and compile again to see if the result is as we analyzed

picture.png

        What we saw was consistent with what we analyzed. Through the study of coercive type conversion, the summary is as follows: 1. Coercive type conversion in C mode: a> is too rude. b> Potential problems are not easily detected. c> It is not easy to locate in the code; 2. New type conversions appear in the form of C++ keywords: a> The compiler can help check potential problems. b> Very convenient to locate in the code. c> Support dynamic type identification (dynamic_cast).


        Welcome to learn C++ language together, you can add me QQ: 243343083 .

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325475090&siteId=291194637