Sobrecarga de funciones (programación)

Sobrecarga de funciones (programación)
Información sobre la plantilla
Concepto:Es un mecanismo que permite asignar el mismo nombre a funciones distintas

Sobrecarga de funciones (Programación). Es un mecanismo que permite asignar el mismo nombre a funciones distintas. Para el compilador estas funciones no tienen nada en común a excepción del identificador, por lo que se trata en realidad de un recurso semántico del lenguaje que solo tiene sentido cuando se asigna el mismo nombre a funciones que realizan tareas similares en objetos diferentes.

Por ejemplo, si tuviésemos objetos que fuesen diversos tipos de polígono (triángulo, cuadrado, pentágono, círculo, etc), tendría sentido denominar getArea a todas las funciones que calculasen el área de las diversas figuras, aunque naturalmente serían funciones distintas en cada caso. También tendría sentido denominar open a las funciones que abrieran un fichero o una línea de comunicación.

Al tratar de los operadores, para el compilador son en realidad funciones, cuyos nombres y sintaxis de invocación son un tanto especiales y que la sobrecarga de estas funciones permite, por ejemplo, extender los conceptos de suma (+), asignación (=) o identidad (==), a objetos distintos de los básicos (preconstruidos en el lenguaje). El hecho de que acciones distintas pero conceptualmente semejantes, puedan ser representadas por el mismo operador (función), resulta a la postre una gran ayuda conceptual. Por ejemplo: puede hablarse de una "suma" de enteros y de una "suma" de complejos que serán gobernadas por versiones distintas del operador suma (+).

Resolución de sobrecarga

Cuando se realiza la invocación de una función sobrecargada, es decir que existen otras del mismo nombre en el mismo ámbito, el compilador decide cual de ellas se utilizará mediante un proceso denominado resolución de sobrecarga ("Overload resolution") aplicando ciertas reglas para verificar cual de las declaraciones se ajusta mejor al número y tipo de los argumentos utilizados. Es decir, donde existe máxima concordancia entre los argumentos actuales y formales. El proceso sigue unas reglas denominadas de congruencia estándar de argumentos; son las siguientes (en el orden precedencia señalado):

1- Concordancia exacta en número y tipo. Esta concordancia puede incluir conversiones triviales, por ejemplo, nombre de matriz a puntero; nombre de función a puntero a función, y tipoX a const tipoX.

2- Concordancia después de realizar promociones de los tipos asimilables a enteros, por ejemplo: char; short; bool; enum (y sus correspondientes versiones unsigned) a int. También de tipos float a double.

3- Concordancia después de realizar conversiones estándar. Por ejemplo: int a double; double a long double; clase-derivada* a Superclase*; tipoX* a void*.

4- Concordancia después de realizar conversiones definidas por el usuario.

5- Concordancia usando la elipsis (...) en funciones con número variable de parámetros.

Si el análisis conduce a que dos funciones distintas concuerdan al mismo nivel máximo, entonces se produce un error y la sentencia es rehusada por el compilador declarando que existe una ambigüedad.

Cuando las versiones sobrecargadas tienen dos o más argumentos, se procede a obtener la mejor concordancia para cada uno utilizando las reglas anteriores. Si una función tiene mejor concordancia que las demás para un argumento y mejor o igual para los restantes, es invocada. En caso contrario la llamada se rehúsa declarando ambigüedad. El orden en que hayan sido declaradas las versiones sobrecargadas no influye para nada en la precedencia anterior. Observe que en todo lo expuesto no se menciona para nada el valor devuelto. Esto significa que para que exista sobrecarga las funciones deben diferir en el tipo y/o número de argumentos. Por tanto, no es válido que solo difieran en el tipo de valor devuelto.

Sobrecarga y valores devueltos

Con objeto de que el mecanismo de sobrecarga sea independiente del contexto, los valores devueltos por las funciones no son tenidos en cuenta a efectos del mecanismo de sobrecarga. Esto tiene importantes consecuencias prácticas. Por ejemplo:

int func (int, char);       // L.1:
int func (float, char);     // Ok versión sobrecargada
void func (int, char);      // Error definición duplicada con L.1

Sobrecarga y ámbito de nombres

Debe tener en cuenta que en C++ no existe el concepto de sobrecarga a través de ámbitos de nombres, por lo que las versiones sobrecargadas deben estar en el mismo ámbito. Por ejemplo:

#include <iostream.h>
namespace UNO {               // Subespacio exterior
  void func (int i) { cout << "func(int) " << endl; }
  namespace UNO_A {          // Subespacio anidado
     void func (float f) { cout << "func(float) " << endl; }
   }
}
void main (void) {            // =======
  int x = 1; float f = 1.1;
  UNO::func(x);
  UNO::func(f);
}
Salida:
func(int)
func(int)

En ambos casos no ha existido sobrecarga de la función a través de los subespacios de nombres; en ambos casos se ha invocado la misma versión de func; la del subespacio exterior. Los ámbitos de las clases derivadas no son una excepción de esta regla general. Cuando se precisa que el mecanismo de la sobrecarga funcione a través de ámbitos distintos, debe utilizarse la declaraciónusing o la directivausing.

Puede Contactar

Fuentes