[C++] Conversión de tipos en C++

1. Conversión de tipos en lenguaje C

En lenguaje C, a menudo ocurre una situación: los tipos en ambos lados del operador son diferentes, o los tipos de parámetros formales y reales no coinciden , en cuyo caso se produce la conversión de tipos. En lenguaje C, la conversión de tipos se divide en dos tipos: conversión de tipos implícita y conversión de tipos explícita .

  1. Conversión de tipo implícita: el compilador realiza automáticamente la conversión durante la fase de mutación. Si se puede convertir, se convertirá automáticamente. Si no se puede convertir, se informará un error.
  2. Conversión de tipo de visualización: manejada por el propio usuario
void test1()
{
    
    
    int i = 1;
    // 隐式类型转换
    double d = i;
    printf("%d, %.2f\n" , i, d);
    int* p = &i;
    // 显示的强制类型转换
    int address = (int)p;
    printf("%x, %d\n" , p, address);
}

La conversión de tipos implícita puede causar problemas en algunos casos:

  1. Por ejemplo, se pierde la precisión de los datos.
  2. La conversión de tipo explícita mezcla todo y el código no es lo suficientemente claro

2. Conversión de tipos en C++

Debido a los defectos de la conversión de tipos en el lenguaje C, C++ introduce cuatro operadores de conversión de conversión con nombre para mejorar la visibilidad de la conversión de tipos: static_cast, reinterpret_cast, const_cast,dynamic_cast

2.1 transmisión estática

static_cast se usa para la conversión de tipos no polimórficos (conversión estática). Cualquier conversión de tipo realizada implícitamente por el compilador se puede usar con static_cast, pero no se puede usar para convertir dos tipos no relacionados.

Uso: static_cast<nombretipo>(nombrevariable); donde nombretipo es el tipo a convertir y nombrevariable es la variable a convertir.

void test1()
{
    
    
    double d = 12.34;
    int a = static_cast<int>(d);
    int b = d;
    cout<< a << " " << b <<endl;
}

Resumen: static_cast es una conversión de tipo implícita de la conversión de tipo de lenguaje C, que requiere que los dos tipos estén relacionados .

2.2 reinterpretar_cast

El operador reinterpret_cast normalmente proporciona una reinterpretación de nivel inferior del patrón de bits del operando y se utiliza para convertir un tipo en otro diferente.

void test2()
{
    
    
    int a = 12;
    //int* p = static_cast<int*>(a);//这里使用static_cast就会报错
    int* p = reinterpret_cast<int*>(a);
    cout << p << endl;
}

Resumen: reinterpret_cast apunta a la conversión de tipos forzada en lenguaje C y no requiere que los dos tipos sean tipos relacionados.

2.3 const_cast

El uso más común de const_cast es eliminar el atributo constante de una variable para facilitar la asignación.

void test3()
{
    
    
    const int a = 10;
    //a = 20;//这里由于a是const修饰的变量,所以不能修改
    int* p = const_cast<int*>(&a);
    *p = 20;
    cout << a << " " << *p << endl;
}

Ampliando conocimientos: si ejecuta el código test3 anterior, encontrará que los avalores de suma impresos *pson diferentes, ¿cuál es el motivo?

imagen-20230928164618764

Esto se debe a que para las variables modificadas constantemente, el compilador pensará que no se modificarán, por lo que se almacenarán en un registro . Cada vez que se accede a ellas, se accederá directamente al valor dentro del registro, por lo que no cambiará. . Si desea que se acceda a él desde la memoria cada vez, debe agregar volatilepalabras clave.

imagen-20230928164919653

2.4 dinámica

Dynamic_cast se utiliza para convertir un puntero/referencia de un objeto de clase principal en un puntero o referencia de un objeto de subclase (conversión dinámica)

Aquí agregamos los conceptos de conversión ascendente y descendente :

Conversión ascendente : conversión de subclase (objeto/puntero/referencia) a clase principal (objeto/puntero/referencia)

Conversión descendente : Conversión de clase principal (objeto/puntero/referencia) a subclase (objeto/puntero/referencia)

Entre ellos, la conversión ascendente está naturalmente permitida, no hay conversión de tipos en el medio y no se generarán objetos temporales, pero la conversión descendente puede causar problemas como matrices fuera de límites, por lo que no es seguro.

class A
{
     
     
public:
    virtual void f() {
     
     }
    
    int _a = 1;
};
class B : public A
{
     
     
public:
    void f() {
     
     }
    int _b = 2;
};
void func(A* ptr)
{
     
     
    B* bptr = (B*)ptr;
    cout << bptr->_b << endl;
    cout << bptr->_a << endl;
}
void test4()
{
     
     
    A aa;
    B bb;
    func(&aa);
    func(&bb);
}

Para objetos de tipo A, si desea acceder al miembro _b, habrá un problema de acceso fuera de límites.

Su dynamic_cast función es convertir un puntero/referencia de un objeto de clase principal en un puntero o referencia de un objeto de subclase (abatido) . hay que tener en cuenta es:

  • dynamic_castSolo se puede utilizar para clases cuya clase principal contenga funciones virtuales.
  • dynamic_castVerificará si la conversión puede tener éxito; si es posible, se convertirá; de lo contrario, devolverá nullptr.
void func(A* ptr)
{
    
    
    //B* bptr = (B*)ptr;
    B* bptr = dynamic_cast<B*>(ptr);
    if(bptr == nullptr)
    {
    
    
        cout << "类型转换错误:出现向下转换" << endl;
        return;
    }
    cout << bptr->_b << endl;
    cout << bptr->_a << endl;
}

imagen-20231001180133033

Nota: En general, debemos evitar el uso de conversiones porque las conversiones desactivan o suspenden la verificación de tipos normal ; por lo tanto, cada vez que usen conversiones, los programadores deben considerar cuidadosamente si hay otras formas diferentes de lograr esto. Para el mismo propósito, si la conversión de tipos es Si no es posible, el alcance del valor de conversión debe limitarse para reducir la posibilidad de errores.


Fin de esta sección…

Supongo que te gusta

Origin blog.csdn.net/weixin_63249832/article/details/133467569
Recomendado
Clasificación