Disponible la nueva versión "donationware" 7.3 de OrganiZATOR
Descubre un nuevo concepto en el manejo de la información.
La mejor ayuda para sobrevivir en la moderna jungla de datos la tienes aquí.

Curso C++

[Home]  [Inicio]  [Índice]


Polimorfismo "versus" Sobrecarga


El lector que se enfrenta por primera vez a estas cuestiones puede sentirse algo confuso respecto a la cuestión. Su línea de razonamiento puede ser más o menos así:

Tengo una clase-base B1 en la que declaro un método mb1 como virtual, con lo que B1 es ahora polimórfica (si declaro la función mb1 virtual pura, entonces B1 será una clase abstracta).

A continuación derivo de B1 dos nuevas clases D1 y D2; en cada una de ellas defino una versión distinta de mb1, con lo que esta función virtual define un comportamiento distinto para objetos d1 y para objetos d2 (es polimórfica).

Pero surge una cuestión: ¿Que pasa si declaro mb1 como un método normal (no virtual) en B1, y a continuación, en las clases derivadas D1 y D2 se redefinen dos nuevas versiones de la función mb1?.

Nota:  este sería justamente el caso del método fun en las clases Base y Derivada del ejemplo de la página anterior.


Evidentemente se tratará de un caso de sobrecarga; las nuevas versiones también eclipsarán a la versión existente en la superclase y el efecto puede ser análogo. Entonces... ¿Cual es la ventaja y la necesidad de las funciones virtuales?.  ¿Cual es la diferencia entre la sobrecarga y el polimorfismo?.  ¿Se trata de una mera cuestión sintáctica?.


La respuesta es Si y No; desde la perspectiva del diseño de lenguajes, desde luego podrían haberse evitado estas diferencias (cosa que efectivamente ocurre en algunos lenguajes), pero en el diseño de C++ se prefirió esta declaración explícita, y desde luego existen diferencias en las condiciones a cumplir, y en los mecanismos subyacentes en uno y otro caso (polimorfismo y sobrecarga).

En primer lugar, en C++ las funciones polimórficas (virtuales) deben ser declaradas como tales de forma explícita al compilador (al menos en la superclase). Además, las declaraciones en la clase-base y en la derivada, deben coincidir en cuanto a número y tipo de los parámetros (también, salvo casos excepcionales, en el valor devuelto). Por contra, el número y tipo de parámetros es justamente lo que diferencia las versiones sobrecargadas de una función [1].

Desde una perspectiva macroscópica puede afirmarse que cuando existen versiones diferentes (sobrecargadas) de una función o método, es precisamente la diferencia de los parámetros utilizados, lo que permite al compilador conocer la versión correcta que debe utilizarse en cada caso. Por contra, cuando existen versiones diferentes (polimórficas) de un método, es la naturaleza del objeto que realiza la invocación lo que permite al compilador conocer la versión que debe utilizar [2].

Cuando un objeto invoca una método normal que está sobrecargado (existen distintas versiones del mismo), la versión correcta de la función que se invoca se conoce ya desde el momento de la compilación, por lo que puede utilizarse enlazado estático.  Por contra, si se utiliza el mecanismo de las funciones virtuales (advirtiendo de este extremo al compilador), se le avisa que la versión correcta no será conocida hasta el tiempo de ejecución, por lo que el compilador no puede utilizar el sistema anterior, debiendo utilizar enlazado dinámico cuyo mecanismo es menos eficiente que el estático.

  Inicio.


[1]  El tipo y número de parámetros es lo que se denomina la "firma" ("signature") de la función.

[2]  Decimos "desde una perspectiva macroscópica" porque en última instancia, son siempre los argumentos los que permiten al compilador decidir cual será el código a utilizar. Aunque en los casos de polimorfismo este argumento sea oculto (el puntero this 4.11.6).