25 - Sobrecarga de métodos


Hemos dicho que una clase está constituida por una serie de atributos (variables) y métodos (funciones). Los atributos deben ser privados y los métodos pueden ser públicos y privados según si se van a poder llamar desde fuera de la clase o no.

Otra característica de C++ con respecto a los métodos es que podemos definir varios con el mismo nombre.

Cuando definimos dos o más métodos con el mismo nombre decimos que los estamos sobrecargando.

La restricción para la sobrecarga de métodos es que los mismos deben diferir en cantidad o tipo de parámetros. Es decir podemos definir dos métodos con el mismo nombre pero uno tenga por ejemplo 3 parámetros y otro tenga 2 parámetros:

void mayor(int x1,int x2,int x3)
void mayor(int x1,int x2)

O que tengan la misma cantidad de parámetros pero sean de distinto tipo:

void mayor(int x1,int x2)
void mayor(char nombre1[40],char nombre2[40])

Problema 1:

Plantear una clase llamada Matematica que implemente cuatro métodos llamados mayor. El primero que reciba como parámetros dos enteros y devuelva el mayor de ellos. El segundo que reciba tres enteros y devuelva el mayor. Los mismo deben hacer los siguientes dos métodos pero recibiendo parámetros de tipo float.

Programa:

#include<iostream>

using namespace std;

class Matematica {
public:
    int mayor(int x1,int x2);
    int mayor(int x1,int x2,int x3);
    float mayor(float x1,float x2);
    float mayor(float x1,float x2,float x3);
};

int Matematica::mayor(int x1,int x2)
{
    if (x1>x2)
        return x1;
    else
        return x2;
}

int Matematica::mayor(int x1,int x2,int x3)
{
    if (x1>x2 && x1>x3)
        return x1;
    else
        if (x2>x3)
            return x2;
        else 
            return x3;
}

float Matematica::mayor(float x1,float x2)
{
    if (x1>x2)
        return x1;
    else
        return x2;
}

float Matematica::mayor(float x1,float x2,float x3)
{
    if (x1>x2 && x1>x3)
        return x1;
    else
        if (x2>x3)
            return x2;
        else 
            return x3;
}

int main()
{
    Matematica m1;
    cout<<"Mayor entre 6 y 8 : ";
    cout<<m1.mayor(6,8);
    cout <<"\n";
    cout<<"Mayor entre 10, 40 y 5 : ";
    cout<<m1.mayor(10,40,5);
    cout <<"\n";
    cout<<"Mayor entre 6.2  y  9.3 : ";
    cout<<m1.mayor(6.2f,9.3f);
    cout <<"\n";
    cout<<"Mayor entre 7 , 12.5  y  4.2 : ";
    cout<<m1.mayor(7.0f,12.5f,4.2f);
    cout <<"\n";
    return 0;
}

Este proyecto lo puede descargar en un zip desde este enlace : SobrecargaMetodos1.zip

Podemos observar que hemos definido cuatro métodos con el mismo nombre llamado mayor:

class Matematica {
public:
    int mayor(int x1,int x2);
    int mayor(int x1,int x2,int x3);
    float mayor(float x1,float x2);
    float mayor(float x1,float x2,float x3);
};

Dos de los mismos difieren en cantidad de parámetros (2 y 3) y cuando tienen la misma cantidad de parámetros difieren en el tipo de parámetros: int y float.

La sobrecarga de métodos nos facilita reducir la cantidad de nombres de métodos cuando realizan la misma actividad, si no existiera la sobrecarga estaríamos obligados a definir cuantro nombres de métodos distintos, por ejemplo:

class Matematica {
public:
    int mayorDosEnteros(int x1,int x2);
    int mayorTresEnteros(int x1,int x2,int x3);
    float mayorDosReales(float x1,float x2);
    float mayorTresReales(float x1,float x2,float x3);
};

Cuando se llama a un método sobrecargado el compilador sabe a cuál método llamar según la cantidad de parámetros que le pasamos:

    cout<<m1.mayor(6,8);
 
   cout<<m1.mayor(10,40,5);

y si hay dos métodos con la misma cantidad de parámetros analiza el tipo de datos que le pasamos:

    cout<<m1.mayor(6,8);

    cout<<m1.mayor(6.2f,9.3f);

Debemos agregar la letra f al final del valor real para indicar que se trata de un valor de tipo float.

Sobrecarga del constructor

Como sabemos el constructor es un método de la clase y como tal podemos sobrecargarlo, es decir definir más de un constructor.

Cuando definimos un objeto de la clase es cuando indicamos a qué constructor llamaremos según nuestras necesidades.

Problema 2:

Crear una clase llamada EstructuraVector. Definir un atributo de tipo vector de 5 elementos enteros. Declarar dos constructores, uno sin parámetros que cargue el vector con valores cero y otro constructor que reciba un entero indicando el valor entero con el que deben inicializarse las componentes.

Programa:

#include<iostream>

using namespace std;

class EstructuraVector {
    int vec[5];
public:
    EstructuraVector();
    EstructuraVector(int valor);
    void imprimir();
};

EstructuraVector::EstructuraVector()
{
    for(int f=0;f<5;f++)
        vec[f]=0;
}

EstructuraVector::EstructuraVector(int valor)
{
        for(int f=0;f<5;f++)
        vec[f]=valor;
}

void EstructuraVector::imprimir()
{
    for(int f=0;f<5;f++)
    {
        cout <<vec[f];
        cout <<"-";
    }
    cout<<"\n\n";
}

int main()
{
    EstructuraVector v1;
    v1.imprimir();
    EstructuraVector v2(12);
    v2.imprimir();
    return 0;
}

Este proyecto lo puede descargar en un zip desde este enlace : SobrecargaMetodos2.zip

Podemos ver que hemos definido dos constructores que difieren en este caso en la cantidad de parámetros que tienen:

class EstructuraVector {
    int vec[5];
public:
    EstructuraVector();
    EstructuraVector(int valor);
    void imprimir();
};

Ahora cuando en la main definimos objetos de la clase EstructuraVector debemos elegir que constructor llamaremos:

    EstructuraVector v1;
    v1.imprimir();
    EstructuraVector v2(12);
    v2.imprimir();

Estamos llamando al constructor que no tiene parámetros cuando definimos el objeto v1 y estamos llamando al constructor que tiene un parámetro cuando definimos el objeto v2.

Problemas propuestos

  1. Implementar una clase que permita cargar un vector de 5 elementos. Definir tres métodos sobrecargados que :
    void imprimir(); //imprime todo el vector
    void imprimir(int hasta);//imprime desde el principio del vector hasta el valor que le pasamos
    void imprimir(int desde,int hasta);//imprime un rango de valores del vector.
    
  2. Plantear una clase llamada Punto con dos atributos llamados x e y.
    Definir dos constructores uno sin parámetros donde cargue en los atributos x e y el valor cero y otro con dos parámetros que cargue los atributos x e y con los valores que llegan al constructor. Imprimir los valores de los atributos.
Solución
#include <iostream>

using namespace std;

class Vector {
    int vec[5];
public:
    void cargar();
    void imprimir();
    void imprimir(int hasta);
    void imprimir(int desde,int hasta);
};

void Vector::cargar()
{
    for(int f=0;f<5;f++)
    {
        cout<<"Ingrese componente:";
        cin>>vec[f];
    }
}

void Vector::imprimir()
{
    for(int f=0;f<5;f++)
    {
        cout<<vec[f]<<"-";
    }
    cout<<"\n\n";
}

void Vector::imprimir(int hasta)
{
    for(int f=0;f<=hasta;f++)
    {
        cout<<vec[f]<<"-";
    }
    cout<<"\n\n";
}

void Vector::imprimir(int desde,int hasta)
{
    for(int f=desde;f<=hasta;f++)
    {
        cout<<vec[f]<<"-";
    }
    cout<<"\n\n";
}


int main()
{
    Vector v1;
    v1.cargar();
    v1.imprimir();
    v1.imprimir(2);
    v1.imprimir(2,4);
    return 0;
}

Este proyecto lo puede descargar en un zip desde este enlace :SobrecargaMetodos3.zip

#include<iostream> using namespace std; class Punto { int x,y; public: Punto(); Punto(int vx,int vy); void imprimir(); }; Punto::Punto() { x=0; y=0; } Punto::Punto(int vx,int vy) { x=vx; y=vy; } void Punto::imprimir() { cout <<"x:"<<x<<" y:"<<y; cout<<"\n\n"; } int main() { Punto p1; p1.imprimir(); Punto p2(30,2); p2.imprimir(); return 0; }

Este proyecto lo puede descargar en un zip desde este enlace :SobrecargaMetodos4.zip

Retornar