Anulación de función y sobrecarga en C ++ y Delphi
Spacessoft 【Dark Night Sand】
En la programación orientada a objetos, cuando la subclase continúa las funciones de la clase base, la subclase puede necesitar lidiar con algunas de las funciones de manera diferente a la clase base, como:
Clase Chuman
{
público:
void saymyname () // imprime el nombre del objeto
{
cout << hola, soy un humano << endl;
}
};
Entonces es obvio, si su subclase tiene una función saymyname con el mismo nombre, el mismo parámetro y valor de retorno (una oración, la misma función), ¿a qué función llamará? Por ejemplo, ahora hay una clase CMark
Clase CMark: Public Chuman
{
público:
void saymyname ()
{
cout << Hola, soy Mark << endl;
}
};
Luego tenemos que preguntar, el siguiente segmento del programa:
Chuman *ph = new Cmark;
if (ph)
ph-> saymyname ();
demás
Cout << Error de reparto! << endl;
eliminar pH;
ph = nulo;
¿Es el hola, soy una marca que queremos imprimir?
No. Salida hola, soy un humano. Es horrible, y cuando señalamos a una persona y le pedimos que diga su nombre, nos dice que es "una persona" en lugar de decir su nombre. La razón de este problema es que apunta a la clase derivada del público con el puntero de la clase base, puede acceder a las funciones miembros de la clase derivada que continúan desde la clase base. Pero si hay funciones con el mismo nombre en la clase derivada, el resultado sigue accediendo a la función del mismo nombre de la clase base, en lugar de la función de la clase derivada misma. De hecho, lo que queremos es determinar cuál de estas funciones del mismo nombre debe llamarse por el tipo real de un objeto, es decir, tal resolución es dinámica. O podemos decir que cuando un objeto es un subtipo, su implementación del mismo nombre en la subclase anula la implementación de la clase base.
Comencemos con el manejo de C ++ de este problema.
Este es un ejemplo típico de polimorfismo en C ++. Para ser específico, es usar palabras clave virtuales para describir la función como una función virtual.
Clase Chuman
{
público:
virtual void saymyname () // imprime el nombre del objeto
{
cout << hola, soy un humano << endl;
}
};
De esta manera, otros códigos siguen siendo los mismos, pero nuestro CMark ya sabe cómo decir su nombre. No importa si la función saymyname () de cmark ha agregado una palabra clave virtual, porque de acuerdo con las disposiciones de la sintaxis de C ++, porque anula la función chuman del mismo nombre, se convierte en virtual en sí mismo. ¿En cuanto a por qué una palabra clave virtual tiene un efecto tan mágico? C ++ FAQ Lite explica esto de la siguiente manera: en C ++, "Las funciones de miembros virtuales se determinan dinámicamente (en tiempo de ejecución). Es decir, las funciones miembros (en tiempo de ejecución) se seleccionan dinámicamente, y la selección se basa en el tipo de objeto., No El tipo de puntero/referencia a ese objeto ". Entonces, nuestro pH encuentra que en realidad apunta a un objeto de Tipo CMark, no el Chuman declarado por su propio tipo, por lo que inteligentemente llama a Saymyname de Cmark.
Delphi usa palabras clave de anulación para ilustrar las anulaciones de funciones. La función sobrescrita debe ser virtual o dinámica, es decir, la función debe contener uno de estos dos indicadores cuando se declara, como:
Dibujo de procedimiento;
Cuando necesite anular, solo necesita redeclarlo con el indicador de anulación en la subclase.
Dibujo de procedimiento;
Sintácticamente, las declaraciones como virtuales y dinámicas son equivalentes. La diferencia es que el primero optimiza la velocidad en la implementación, mientras que el segundo optimiza el tamaño del código.
¿Qué pasa si tanto la clase base como la subclase contienen el mismo nombre de función y parámetro, y el indicador de anulación no se agrega a la subclase? Esto también es sintácticamente correcto. Esto significa que la implementación de la función de la función de la subclase oculta la implementación de la clase base, aunque ambos existen en la clase derivada. Luego volvamos a la situación que se muestra en el primer ejemplo al comienzo de este artículo: cuando señalamos a una persona y le pedimos que diga su propio nombre, nos dice que es "una persona", en lugar de decir la suya. nombre.
Vale la pena señalar que, a diferencia de la función de sobrecarga y la función de sobrecarga que a menudo llamamos sobrecarga en C ++, en Delphi, solo la sobrecarga es lo que generalmente llamamos sobrecarga. Por supuesto, cuando la sobrecarga descartada de la función es el mismo que los parámetros de la función de la clase base, la implementación de la clase base está oculta, al igual que la mencionada anteriormente. Anular significa hacer que la función sobrescribida sea invisible y, de hecho, sobrescribir, y la implementación original desaparecerá. Por esta razón, muchos artículos e incluso algunos libros han traducido erróneamente la anulación en sobrecarga, lo que creo que no es apropiado.