Conversión automática y reemplazo de tipo forzado de clases C ++

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
{
    
    
privateint 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 explicitcalificadores (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 explicitla 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, hay Dog(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=14conversió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
{
    
    
privateint 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"

Supongo que te gusta

Origin blog.csdn.net/rjszz1314/article/details/104526762
Recomendado
Clasificación