Conversión automática y reemplazo de tipo forzado de clases C ++
0X00 Prólogo
En C ++, el diseño de una clase es muy importante. La calidad del diseño de una clase depende de si su interfaz es buena, es decir, del diseño de la función
A veces, es posible que necesitemos diseñar una variedad de interfaces para mejorar el polimorfismo de la clase.
Hoy hablaremos del problema de la transformación.
Antes de eso, definamos una clase como nuestra
class Dog
{
private:
int GoOutTimes; //表示一周遛狗的次数
double Kilo; //表示一周遛狗走的公里数
double Time; //表示一周遛狗的时间
public:
Dog(double ti); //构造函数:初始化遛狗时间
Dog(int times,double ki); //构造函数:初始化遛狗次数与遛狗距离
Dog(); //默认构造函数
~Dog(); //析构函数
void show_Ki() const; //展示公里数
void show_ti() const; //展示时间
};
0X10 Conversión automática durante la inicialización
1. Usando la conversión implícita del constructor Como
puede ver, la clase anterior proporciona tres constructores:
Dog(double ti);
Dog(int times,double ki);
Dog();
Podemos llamar al constructor para inicializar el objeto de la clase cuando lo declaramos:
Dog Chichi(12.6);
Dog Mimi(3,10.2);
Dog Lolo();
Dado que un objeto Perro representa la situación de salida semanal de un perro (días, kilómetros y tiempo), ¿podemos proporcionar algunos métodos para convertir números enteros o de coma flotante en objetos Perro?
Ya que tenemos el constructor correspondiente:
Dog(double ti);
entonces podemos usar el constructor para convertir el tipo double al tipo Dog. ¿No es raro?
Sin embargo, funciona
Dog myDog;
myDog=14.3;
Cuando el programa se ejecuta myDog=14.3;
, el compilador verificará si hay constructor Dog(double)
este constructor, ya que lo hay, luego usará Dog(double)
para creartemporalDog object, y luego adopte uno por uno, miembros de la asignación temporal para copiar el objeto al myDog, este proceso se llama conversión implícita , porque se realiza automáticamente.
Una cosa a la que debemos prestar especial atención
Solo un constructor que acepta un parámetro se puede utilizar como función de conversión
Esa Dog(int times,double ki);
función no se usa para la conversión, a menos que pueda proporcionar un valor predeterminado para el segundo argumento :
Dog(int times,double ki=8.9);
Solo entonces el usuario puede convertir int
2. Explícito bajo restricción explícita
Pero a veces, para garantizar la seguridad, es necesario evitar que suceda este comportamiento inseguro. (Suena contradictorio, pero esto es exactamente lo que los diseñadores de lenguajes deben considerar)
En otras palabras, apague esta conversión implícita
Por tanto, la introducción de explicit
calificadores (explícitos), bajo su modificación, indica que para la función modificada, dicha conversión implícita no funcionará:
explicit Dog(double ti);
En este momento, la conversión implícita anterior no funcionará, pero la conversión explícita aún se puede usar para forzar la conversión:
Dog myDog;
//error
myDog = 13.2
//right
myDog = Dog(13.2);
myDog = (Dog) 13.2;
3. Resumen
Para resumir, acabo de hablar:
el uso de explicit
la palabra clave Dog (double)
solo se puede usar para emitir explícitamente; de lo
contrario, también se puede usar para las siguientes conversiones implícitas:
-
Al inicializar un objeto Dog a un valor doble
-
Al pasar un valor doble a un objeto Perro
-
Al pasar un valor doble a una función que acepta un parámetro Dog
-
Cuando el valor de retorno se declara en función de Dog e intenta devolver un valor doble
-
En cualquiera de los casos anteriores, cuando se utiliza un tipo integrado que se puede convertir en un tipo doble
Quizás el último punto no sea claro para todos.
Tomamos un ejemplo, tomamos la clase superior, hayDog(double ti);
un constructor, todos lo sabemos, el tipo de doble conversión es posible para Dog:
Dog myDog;
myDog = 14.5;
Sin embargo, el siguiente código también es posible:
Dog myDog;
myDog = 14;
De hecho, también es muy fácil de entender porque el tipo int (14) se puede convertir al tipo double (14.0), por lo que esto es legal.
Pero también debemos prestar especial atención a: ambigüedad
Qué significa eso?
Clase de perro si tenemos tal función Dog(long)
, ¡la myDog=14
conversión no será válida!
Dado que int se puede convertir en double o long, existe un problema de ambigüedad que dificulta el compilador.
Entonces el compilador atacará.
Función de conversión personalizada 0X11
Mencionamos anteriormente que podemos convertir tipos básicos (como double) en nuestros objetos de clase, siempre que haya un constructor correspondiente.
Entonces, ¿el objeto de clase se puede convertir directamente en un tipo básico? (Suena como una idea muy extraña de nuevo), así:
Dog Nana(7.6);
double Time=Nana;
¡La respuesta es sí!
Sin embargo, lo que necesitamos en este momento no es un constructor, sino una función de operador especial——Función de conversión
Entonces, ¿cómo crear una función de conversión?
Supongamos que queremos convertir al tipo typeName, necesitamos usar esta forma de función de conversión:
operator ypename ()
Tenga en cuenta lo siguiente:
-
La función de conversión debe ser un método de clase;
-
La función de conversión no puede especificar el tipo de retorno;
-
La función de conversión no puede tener parámetros;
Ahora agregamos las funciones para convertir objetos Dog en tipos int y double a la declaración de clase:
class Dog
{
private:
int GoOutTimes; //表示一周遛狗的次数
double Kilo; //表示一周遛狗走的公里数
double Time; //表示一周遛狗的时间
public:
Dog(double ti); //构造函数:初始化遛狗时间
Dog(int times,double ki); //构造函数:初始化遛狗次数与遛狗距离
Dog(); //默认构造函数
~Dog(); //析构函数
void show_Ki() const; //展示公里数
void show_ti() const; //展示时间
operator int() const; //转换为 int
operator double() const; //转换为 double
El contenido de implementación de la función puede ser especificado por usted mismo:
//将遛狗天数返回加1
Dog::operator int() const
{
return GoOutTimes+1;
}
//返回一周遛狗平均公里数
Dog::operator double() const
{
return Kilo/7;
}
0X20 Epílogo
Para expandir el polimorfismo de clases, C ++ proporciona muchos métodos para diseñar clases, si podemos usarlos bien, será muy útil para nuestro trabajo de codificación.
Espero que el contenido de hoy pueda ser útil para todos ~
Gracias a todos ~
¡Nos vemos mañana!
————————————————————————————————————————————————— ————
Referencia: "C ++ Primer Plus 6th Edition"