A juzgar por la redacción de su pregunta (utilizó la palabra "ocultar"), ya sabe lo que está sucediendo aquí. El fenómeno se llama "ocultamiento de nombre". Por alguna razón, cada vez que alguien pregunta por qué se esconde el nombre, las personas que responden dicen que esto se llama "nombre oculto" y explican cómo funciona (que probablemente ya conozca), o explican cómo anularlo (sobre el cual nunca preguntaste), pero a nadie parece importarle abordar la pregunta real de "por qué".
La decisión, la lógica detrás del nombre oculto, es decir qué que en realidad fue diseñado en C++, es evitar cierta contrario a la intuición, imprevisto y el comportamiento potencialmente peligroso que podría tener lugar si el conjunto heredado de funciones sobrecargadas se les permitió mezclar con el conjunto actual de sobrecargas en la clase dada. Probablemente sepa que en C++ la resolución de sobrecarga funciona al elegir la mejor función del conjunto de candidatos. Esto se hace al hacer coincidir los tipos de argumentos con los tipos de parámetros. Las reglas de coincidencia pueden ser complicadas a veces y, a menudo, pueden dar lugar a resultados que un usuario no preparado podría percibir como ilógicos. Agregar nuevas funciones a un conjunto de otras ya existentes puede dar lugar a un cambio bastante drástico en los resultados de resolución de sobrecarga.
Por ejemplo, supongamos que la clase base B
tiene una función miembro foo
que toma un parámetro de tipo void *
, y todas las llamadas a foo(NULL)
se resuelven a B::foo(void *)
.Digamos que no hay ningún nombre oculto y este B::foo(void *)
es visible en muchas clases diferentes que descienden de B
. Sin embargo, digamos que en algún descendiente [indirecto, remoto] D
de la clase B
se define una función foo(int)
. Ahora, sin nombre oculto, D
tiene tanto foo(void *)
como foo(int)
visibles y participando en la resolución de sobrecarga. ¿Qué función resolverán las llamadas a foo(NULL)
, si se realiza a través de un objeto de tipo D
? Se resolverán en D::foo(int)
, ya que int
es una mejor coincidencia para el cero integral (es decir, NULL
) que cualquier tipo de puntero. Por lo tanto, en toda la jerarquía, las llamadas a foo(NULL)
se resuelven en una función, mientras que en D
(y menos) se resuelven de repente a otra.
Este comportamiento se consideró indeseable cuando se diseñó el idioma. Como mejor enfoque, se decidió seguir la especificación de "ocultamiento de nombre", lo que significa que cada clase comienza con una "hoja limpia" con respecto al nombre de cada método que declara. Para anular este comportamiento, se requiere una acción explícita del usuario: originalmente una redeclaración de método (s) heredado (actualmente en desuso), ahora un uso explícito de use-declaration.
Como correctamente observó en su publicación original (me refiero a la observación "No polimórfico"), este comportamiento puede ser visto como una violación de la relación IS-A entre las clases. Esto es cierto, pero aparentemente en aquel entonces se decidió que, al final, esconderse sería un mal menor.
pregunta brillante, descubrí esto recientemente también –
Duplicado: http://stackoverflow.com/questions/411103/function-with-same-name-but-different-signature-in-derived-class – psychotik
Pase por el siguiente enlace y encontrarás tu respuesta. [El artículo] (http://www.research.att.com/~bs/bs_faq2.html#overloadderived) fue escrito por Bjarne Stroustrup. – Ashish