Saltar al contenido

¿Qué es un constructor de conversión en C ++? ¿Para qué sirve?

Luego de de esta larga búsqueda de datos hemos podido solucionar esta interrogante que tienen ciertos de nuestros lectores. Te brindamos la solución y deseamos servirte de gran ayuda.

Solución:

La definición de un constructor de conversión es diferente entre C ++ 03 y C ++ 11. En ambos casos debe ser unexplicit constructor (de lo contrario, no estaría involucrado en conversiones implícitas), pero para C ++ 03 también debe ser invocable con un solo argumento. Es decir:

struct foo

  foo(int x);              // 1
  foo(char* s, int x = 0); // 2
  foo(float f, int x);     // 3
  explicit foo(char x);    // 4
;

Los constructores 1 y 2 son constructores de conversión en C ++ 03 y C ++ 11. El constructor 3, que debe tomar dos argumentos, es solo un constructor de conversión en C ++ 11. El último, el constructor 4, no es un constructor de conversión porque es explicit.

  • C ++ 03: §12.3.1

    Un constructor declarado sin el especificador de funciónexplicit que se puede llamar con un solo parámetro especifica una conversión del tipo de su primer parámetro al tipo de su clase. Dicho constructor se denomina constructor de conversión.

  • C ++ 11: §12.3.1

    Un constructor declarado sin el especificador de funciónexplicit especifica una conversión de los tipos de sus parámetros al tipo de su clase. Dicho constructor se denomina constructor de conversión.

¿Por qué se considera que los constructores con más de un parámetro son constructores de conversión en C ++ 11? Esto se debe a que el nuevo estándar nos proporciona una sintaxis útil para pasar argumentos y devolver valores usando listas-inicial-reforzadas. Considere el siguiente ejemplo:

foo bar(foo f)

  return 1.0f, 5;

La capacidad de especificar el valor de retorno como lista-inicial-reforzada se considera una conversión. Esto usa el constructor de conversión para foo eso toma un float y un int. Además, podemos llamar a esta función haciendo bar(2.5f, 10). Esto también es una conversión. Dado que son conversiones, tiene sentido que los constructores que utilizan sean conversión de constructores.

Es importante señalar, por lo tanto, que hacer que el constructor de foo que toma un float y un int tener el explicit El especificador de función detendría la compilación del código anterior. La nueva sintaxis anterior solo se puede usar si hay un constructor de conversión disponible para hacer el trabajo.

  • C ++ 11: §6.6.3:

    A return declaración con un lista-inicial-reforzada inicializa el objeto o la referencia que se devolverá desde la función mediante la inicialización de la lista de copias (8.5.4) de la lista de inicializadores especificada.

    §8.5:

    La inicialización que ocurre […] en el paso de la discusión […] se llama inicialización de copia.

    §12.3.1:

    Un constructor explícito construye objetos al igual que los constructores no explícitos, pero lo hace solo cuando se utiliza explícitamente la sintaxis de inicialización directa (8.5) o las conversiones (5.2.9, 5.4).

Conversión implícita con converting constructor

Hagamos el ejemplo de la pregunta más complejo.

class MyClass

  public:
     int a, b;
     MyClass( int i ) 
     MyClass( const char* n, int k = 0 ) 
     MyClass( MyClass& obj ) 

Los dos primeros constructores son constructores de conversión. El tercero es un constructor de copia y, como tal, es otro constructor de conversión.

Un constructor de conversión permite la conversión implícita del tipo de argumento al tipo de constructor. Aquí, el primer constructor permite la conversión desde un int a un objeto de clase MyClass. El segundo constructor permite la conversión desde un string a un objeto de clase MyClass. Y tercero … de un objeto de clase MyClass a un objeto de clase MyClass !

Para ser un constructor de conversión, el constructor debe tener un solo argumento (en el segundo, el segundo argumento tiene un valor predeterminado) y debe declararse sin la palabra clave explicit.

Entonces, la inicialización en main puede verse así:

int main()

    MyClass M = 1 ;
    // which is an alternative to
    MyClass M = MyClass(1) ;

    MyClass M = "super" ;
    // which is an alternative to
    MyClass M = MyClass("super", 0) ;
    // or
    MyClass M = MyClass("super") ;

Constructores y palabras clave explícitas

Ahora, ¿y si hubiéramos usado el explicit palabra clave?

class MyClass

  public:
     int a, b;
     explicit MyClass( int i ) 

Entonces, el compilador no aceptaría

   int main()
    
        MyClass M = 1 ;
    

ya que esta es una conversión implícita. En cambio, tienes que escribir

   int main()
    
        MyClass M(1) ;
        MyClass M = MyClass(1) ;
        MyClass* M = new MyClass(1) ;
        MyClass M = (MyClass)1;
        MyClass M = static_cast(1);
    

explicit La palabra clave siempre se debe usar para evitar la conversión implícita de un constructor y se aplica al constructor en una declaración de clase.

Un constructor de conversión es un constructor de un solo parámetro que se declara sin el especificador de función explícito. El compilador usa constructores de conversión para convertir objetos del tipo del primer parámetro al tipo de la clase del constructor de conversión.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *