Beruflich Dokumente
Kultur Dokumente
SESION 15
Clases IV Operadores Sobrecargados
MARCO TEORICO
+, -, *, /, %, ^, &, |, (,), <, >, <=, >=, <<, >>, ==, !=, &&, ||, =, +=. -=, *=, /=, %=, ^=,
&=, |=, <<=,>>=, [], (),->, new y delete.
ACTIVIDADES
Los operadores binarios, son aquellos que requieren dos operandos, como la suma o la resta.
#include <iostream.h>
#include <stdlib.h>
class Tiempo {
public:
Tiempo(int h=0, int m=0) : hora(h), minuto(m) {}
void Mostrar();
Tiempo operator+(Tiempo h);
private:
int hora;
int minuto;
};
Tiempo Tiempo::operator+(Tiempo h)
{
Tiempo temp;
temp.minuto = minuto + h.minuto;
temp.hora = hora + h.hora;
if(temp.minuto >= 60) {
temp.minuto -= 60;
temp.hora++;
}
return temp;
}
void Tiempo::Mostrar()
{
cout << hora << ":" << minuto << endl;
}
int main()
{
Tiempo Ahora(12,24), T1(4,45);
T1 = Ahora + T1;
T1.Mostrar();
(Ahora + Tiempo(4,45)).Mostrar();
system("PAUSE");
return 0;
}
2. Modificar el ejercicio anterior de tal forma que permita controlar tambin los segundos.
3. Sobrecargue el operador para que permita resta dos objetos Tiempo.
Cuando tenemos una clase que almacena punteros a determinados tipos de datos, y hacemos
una asignacin: C2 = C1;
Lo que realmente copiamos no es la cadena, sino el puntero. Ahora los dos punteros de las
cadenas C1 y C2 estn apuntando a la misma direccin. Qu pasar cuando destruyamos los
objetos?. Al destruir C1 se intentar liberar la memoria de su puntero cadena, y al destruir C2
tambin, pero ambos punteros apuntan a la misma direccin y el valor original del puntero de C2
se ha perdido, y su memoria no puede ser liberarada.
#include <iostream.h>
#include <stdlib.h>
#include <string.h>
class Cadena {
public:
Cadena(char *cad);
Cadena() : cadena(NULL) {};
~Cadena() { delete[] cadena; };
void Mostrar() const;
Cadena& operator=(const Cadena &c);
private:
char *cadena;
};
Cadena::Cadena(char *cad)
{
cadena = new char[strlen(cad)+1];
strcpy(cadena, cad);
}
delete[] cadena;
if(c.cadena) {
cadena = new char[strlen(c.cadena)+1];
strcpy(cadena, c.cadena);
}
else cadena = NULL;
}
return *this;
}
int main()
{
Cadena C1("Cadena de prueba"), C2;
C2 = C1;
C1.Mostrar();
C2.Mostrar();
Cadena C3("Hipolito");
C1=C2=C3;
C1.Mostrar();
C2.Mostrar();
C3.Mostrar();
return 0;
}
Hay que tener en cuenta la posibilidad de que se asigne un objeto a s mismo. Por eso
comparamos el puntero this con la direccin del parmetro, si son iguales es que se trata del
mismo objeto, y no debemos hacer nada. Esta es una de las situaciones en las que el puntero this
es imprescindible.
Tambin hay que tener cuidado de que la cadena a copiar no sea NULL, en ese caso no debemos
copiar la cadena, sino slo asignar NULL a cadena.
Y por ltimo, tambin es necesario retornar una referencia al objeto, esto nos permitir escribir
expresiones como estas: C1=C2=C3;
include <iostream.h>
#include <stdlib.h>
#include <string.h>
class persona {
public:
persona(char *nom, char *ape);
persona() : nombre(NULL), apellido(NULL) {};
~Cadena() { delete[] nombre; delete[] apellido; };
void Mostrar() const;
persona& operator=(const persona &p);
private:
char *nombre;
char *apellido;
};
6. Realice el siguiente programa en c++ donde sobrecargamos el operador de > para averiguar
cul de las horas es mayor.
#include <iostream.h>
#include <stdlib.h>
class Tiempo {
public:
Tiempo(int h=0, int m=0) : hora(h), minuto(m) {}
void Mostrar();
Tiempo operator+(Tiempo h);
bool operator>(Tiempo h);
private:
int hora;
int minuto;
};
Tiempo Tiempo::operator+(Tiempo h)
{
Tiempo temp;
temp.minuto = minuto + h.minuto;
temp.hora = hora + h.hora;
if(temp.minuto >= 60) {
temp.minuto -= 60;
temp.hora++;
}
return temp;
}
bool Tiempo::operator>(Tiempo h)
{
return (hora > h.hora || (hora == h.hora && minuto > h.minuto));
}
void Tiempo::Mostrar()
{
cout << hora << ":" << minuto << endl;
}
int main()
{
Tiempo Ahora(12,24), T1(4,45);
T1 = Ahora + T1;
T1.Mostrar();
(Ahora + Tiempo(4,45)).Mostrar();
if(Tiempo(1,32) > Tiempo(1,12)) cout << "1:32 es mayor que 1:12" <<
endl;
else cout << "1:32 es menor o igual que 1:12" << endl;
system("PAUSE");
return 0;
}
7. Modifique el ejercicio 2 de tal forma que podamos averiguar cual Tiempo es mayor.
8. Sobrecargar el operador de < de tal forma que podamos averiguar cul es el Tiempo
menor.
#include <iostream.h>
#include <stdlib.h>
class Tiempo {
public:
Tiempo(int h=0, int m=0) : hora(h), minuto(m) {}
void Mostrar();
Tiempo operator+(Tiempo h);
bool operator>(Tiempo h);
void operator+=(Tiempo h);
private:
int hora;
int minuto;
};
Tiempo Tiempo::operator+(Tiempo h)
{
Tiempo temp;
temp.minuto = minuto + h.minuto;
temp.hora = hora + h.hora;
if(temp.minuto >= 60) {
temp.minuto -= 60;
temp.hora++;
}
return temp;
}
bool Tiempo::operator>(Tiempo h)
{
return (hora > h.hora || (hora == h.hora && minuto > h.minuto));
}
void Tiempo::operator+=(Tiempo h)
{
minuto += h.minuto;
hora += h.hora;
while(minuto >= 60) {
minuto -= 60;
hora++;
}
}
void Tiempo::Mostrar()
{
cout << hora << ":" << minuto << endl;
}
int main()
{
Tiempo Ahora(12,24), T1(4,45);
T1 = Ahora + T1;
T1.Mostrar();
(Ahora + Tiempo(4,45)).Mostrar();
if(Tiempo(1,32) > Tiempo(1,12)) cout << "1:32 es mayor que 1:12" << endl;
else cout << "1:32 es menor o igual que 1:12" << endl;
Ahora += Tiempo(1,32);
Ahora.Mostrar();
system("PAUSE");
return 0;
}
Si intentamos sobrecargar el operador suma con la clase Cadena usando el mismo sistema que
con Tiempo, veremos que no funciona.
Cuando nuestras clases tienen punteros con memoria dinmica asociada, la sobrecarga de
funciones y operadores puede complicarse un poco.
#include <iostream.h>
#include <stdlib.h>
#include <string.h>
class Cadena {
public:
Cadena(char *cad);
Cadena() : cadena(NULL) {};
~Cadena() { delete[] cadena; };
void Mostrar() const;
Cadena& operator=(const Cadena &c);
Cadena operator+(const Cadena &);
private:
char *cadena;
};
Cadena::Cadena(char *cad)
{
cadena = new char[strlen(cad)+1];
strcpy(cadena, cad);
}
int main()
{
Cadena C1, C2("Primera parte");
C1 = C2 + " Segunda parte";
C1.Mostrar();
return 0;
}
11. Para evitar eso tenemos que sobrecargar el constructor copia, afortunadamente es sencillo ya
que disponemos del operador de asignacin, sin olvidar que tenemos que inicializar los datos
miembros, el constructor copia no deja de ser un constructor: