En C y C++, si el compilador encuentra una expresión o una llamada a función que usa un tipo que no es el que se requiere, a menudo podrá realizar una conversión automática de tipos desde el tipo que tiene al tipo que necesita. En C++, puede conseguir este mismo efecto para los tipos definidos por el usuario creando funciones de conversión automática de tipos. Estas funciones se pueden ver en dos versiones: un tipo particular de constructores y un operador sobrecargado.
Si define un constructor que toma como su único argumento un objeto (o referencia) de otro tipo, ese constructor permite al compilador realizar una conversión automática de tipos. Por ejemplo:
//: C12:AutomaticTypeConversion.cpp // Type conversion constructor class One { public: One() {} }; class Two { public: Two(const One&) {} }; void f(Two) {} int main() { One one; f(one); // Wants a Two, has a One } ///:~
Listado 12.18. C12/AutomaticTypeConversion.cpp
Cuando el compilador ve que f()
es invocada pasando un objeto
One
, mira en la declaración de f()
y
ve que requiere un Two
. Entonces busca si hay alguna manera
de conseguir un Two
a partir de un
One
, encuentra el constructor
Two::Two(One)
y lo llama. Pasa el objeto
Two
resultante a f()
.
En este caso, la conversión automática de tipos le ha salvado del problema de
definir dos versiones sobrecargadas de f()
. Sin embargo el
coste es la llamada oculta al constructor de Two
, que puede
ser importante si está preocupado por la eficiencia de las llamadas a
f()
,
Hay veces en que la conversión automática de tipos vía constructor puede
ocasionar problemas. Para desactivarlo, modifique el constructor anteponiéndole
la palabra reservada explicit
(que sólo funciona con constructores). Así
se ha hecho para modificar el constructor de la clase Two
en el ejemplo anterior:
//: C12:ExplicitKeyword.cpp // Using the "explicit" keyword class One { public: One() {} }; class Two { public: explicit Two(const One&) {} }; void f(Two) {} int main() { One one; //! f(one); // No auto conversion allowed f(Two(one)); // OK -- user performs conversion } ///:~
Listado 12.19. C12/ExplicitKeyword.cpp
Haciendo el constructor de Two
explícito, se le dice al
compilador que no realice ninguna conversión automática de tipos usando ese
constructor en particular (sí se podrían usar otros constructores no explícitos
de esa clase para realizar conversiones automáticas). Si el usuario quiere que
ocurra esa conversión, debe escribir el codigo necesario. En el código de
arriba, f(Two(one))
crea un objeto temporal de tipo
Two
a partir de one
, justo como el
compilador hizo automáticamente en la versión anterior.