Vous êtes sur la page 1sur 141

Tema 3

Abstraccion de datos en C++ : Clases


Gabriel Navarro
Metodologa de la Programaci on
Grado en Ingeniera Informatica
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases

Indice
Denicion de una clase
Implementacion de una clase
Constructores y destructores
El puntero this
Modicadores
const
static
friend
inline
Sobrecarga de operadores
operador de asignacion
operador []
operadores aritmeticos
operadores de incremento y decremento
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Motivaci on: struct
Recordemos que un struct es un tipo de dato adicional
Denicion de un struct
struct identicador struct{
tipo1 variable1;
tipo2 variable2;
....
tipoN variableN;
};
Declaracion de una variable de tipo struct
identicador struct identificador variable;
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Motivaci on: struct
CUIDADO
Un struct NO puede contener una instancia de s misma
struct Persona {
char nombre[30];
Persona amigo; // error de sintaxis
};
Aunque s puede contener un puntero haca el mismo tipo de
struct (struct autorreferencial), por ejemplo, las listas enlazadas
Ejemplo del Tema 2
struct Persona {
char nombre[30];
Persona * amigo;
};
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Motivaci on: struct
Algunos problemas de los struct (a resolver con las clases):
Iniciacion de datos
los struct no se inicializan de forma automatica
deben inicializarse campo a campo
podran inicializarse de forma incorrecta
Sobrecarga de operadores
s esta sobrecargado =, pero no, << ni >>
Reutilizacion del software
al cambiar la implementacion del struct hay que cambiar el
resto del programa que lo utiliza
Proteccion del software
el programador manipula directamente los datos
no hay una interfaz para garantizar una correcta
manipulacion de los datos
Ocultacion del software
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Declaraci on de una clase
Las clases son una evolucion de los struct. Ademas contener datos,
se denen operadores con ellos
Declaracion de una clase
class identicador clase{
public:
declaracion de datos publicos;
funciones (metodos) publicos;
private:
declaracion de datos privados;
funciones (metodos) privados;
};
Declaracion de un objeto
identicador clase identificador objeto;
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Declaraci on de una clase
Ejemplo: Declaracion sencilla de la clase Tiempo
class Tiempo{
public:
void establecerHora (int , int , int );
void imprimir ();
private:
int hora;
int minutos;
int segundos;
};
Ejemplo: Declaracion de un objeto de la clase Tiempo
Tiempo horacenar;
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Declaraci on de una clase
Algunos comentarios
para declarar una clase se utiliza la palabra reservada class
se declaran en el mismo lugar que los struct, al comienzo del
chero de codigo fuente, despues de la inclusion de bibliotecas
y declaracion de constantes y variables globales.
a los datos declarados en la clase se les llama datos o
campos miembro de la clase
a las funciones declarados en la clase se les llama funciones o
metodos miembro de la clase
los datos especican las propiedades del objeto
los metodos modelan su comportamiento y las acciones que
pueden realizar
una variable de tipo clase es lo que se llama objeto. Esto
es, un objeto es a una clase lo que una variable es a un tipo
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Declaraci on de una clase
Las palabras reservadas public y private se conocen como
especicadores de acceso a miembro
Especicadores de acceso a miembro
los datos o metodos declarados despues de public: son
accesibles desde cualquier punto del que sea accesible la
clase
los datos o metodos declarados despues de private: solo son
accesibles para los metodos miembro de la clase
si no se utiliza ning un especicador se consideran privados
existe un especicador mas: protected (se vera en la
asignatura Estructuras de Datos)
los metodos p ublicos es lo que se llama interfaz de la clase
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Declaraci on de una clase
Ejemplo de acceso a los datos p ublicos y privados
class Punto2D{
public:
int x;
private:
int y;
};
int main(){
Punto2D punto;
/*** como en las estructuras, se accede con el operador . ***/
punto.x=3; // correcto: x es un dato p ublico
punto.y=3;//error: y solo manipulable por funciones miembro
}
Error: int Punto2D::y is private within this context
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Declaraci on de una clase
Al igual que con los struct, el acceso a los miembros de una clase
se realiza con el operador .
Ejemplo de acceso
Punto2D punto;
punto.x=3;
Tiempo horacomer;
horacomer.imprimir();// tambien con las funciones
o bien, mediante el operador > a traves de un puntero
Ejemplo de acceso
Punto2D *ptrpunto;
ptrpunto->x = 3;
Tiempo *ptrcomer;
ptrcomer->imprimir();
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Implementaci on de una clase
los metodos miembros de una clase:
se declaran en la declaracion de la clase como cualquier otra
funcion en C++
a veces se especica incluso su denicion (funciones inline )
si se denen fuera de la declaracion de la clase, se utiliza el
operador ::
Uso generico
tipo retorno clase::funcion( tipo1 ,...,tipoN )
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Implementaci on de una clase
Implementacion de la clase Tiempo
#include <iostream>
using namespace std;
class Tiempo{
public:
void establecerHora (int , int );
void imprimir ();
private:
int hora;
int minutos;
};
void Tiempo::imprimir (){
cout << hora << : << minutos << endl;
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Implementaci on de una clase
Implementacion de la clase Tiempo
void Tiempo::establecerHora (int n, int m){
hora=n; minutos=m;
}
int main(){
Tiempo horacomer;
horacomer.establecerHora(14,30);
horacomer.imprimir ();
horacomer.establecerHora(15,25);
horacomer.imprimir ();
} // Observese el caracter secuencial
14:30
15:25
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Denici on de una clase: separaci on de la interfaz
La implementacion de una clase se realiza de la siguiente manera:
En un chero de cabecera (.h) se dene la clase (interfaz)
Fichero Tiempo.h
#ifndef Tiempo_H
#dene Tiempo_H
class Tiempo{
public:
void establecerHora (int , int );
void imprimir ();
private:
int hora;
int minutos;
};
#endif
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Denici on de una clase: separaci on de la interfaz
En un chero de codigo fuente (.cpp) se denen los metodos
de la clase (implementacion de la interfaz)
Fichero Tiempo.cpp
#include <iostream>
#include Tiempo.h
using namespace std;
void Tiempo::imprimir (){
cout << hora << : << minutos << endl;
}
void Tiempo::establecerHora (int n, int m){
hora=n; minutos=m;
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Denici on de una clase: separaci on de la interfaz


Tiempo.h
Tiempo.cpp
OO


Tiempo.h
principal.cpp

Tiempo.cpp Tiempo.o
//
Tiempo.o libtiempo.a
//
principal.cpp principal.o
//
libtiempo.a
principal.exe

?
?
?
?
?
principal.o
principal.exe
??





El usuario solo recibira el chero de cabecera, la libreria y la
documentacion
Consecuencias
se oculta la implementacion de la clase al usuario
el usuario puede utilizar la interfaz, no manipularla
no puede hacer mal uso (software mas robusto)
se puede cambiar la implementacion sin afectar al usuario
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Representaci on en memoria
Los objetos son mas peque nos de lo que parecen:
Cada objeto contiene los datos miembro
Hay una unica copia de los metodos miembro para todos los objeto
Tama no de un objeto
class Tiempo{
public:
void establecerHora (int , int );
private:
int hora;
int minutos;
};
int main(){
Tiempo horacomer;
cout << sizeof(horacomer) << << sizeof(Tiempo);}
8 8
Importante: no se reserva memoria al denir la clase
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Ampliaci on: documentaci on de una clase con Doxygen
La documentacion de una clase con Doxygen conlleva la
implementacion de comentarios en 3 partes fundamentales:
En la declaracion de la clase. Se debe hacer una breve
descripcion de la clase, junto con una descripcion un poco
mas larga de que representa y como utilizarla (metodos,
atributos p ublicos, etc.)
En la declaracion de atributos de la clase. Se debe comentar
cada atributo por separado, indicando que representa dentro
de la clase, para que se utiliza y sus restricciones.
En la declaracion de metodos de la clase. Se realiza de igual
forma que la documentacion de modulos con Doxygen.
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Ampliaci on: documentaci on de una clase con Doxygen
Ejemplo: Documentacion general de la clase Tiempo
/**
* @brief TDA Tiempo
*
* Una instancia \a c de la clase \b Tiempo es un objeto
* que representa un memento determinado del da expresado
* en horas y minutos.
* Lo representaremos de la forma \a hora : \a minutos. \n
*
* Un ejemplo de su uso:
* @include ejemplotiempo.cpp
*/
class Tiempo{
...
};
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Ampliaci on: documentaci on de una clase con Doxygen
La documentacion de los atributos se realiza a la derecha de su
declaracion, y utilizando el comando siguiente:
/**< Comentario del atributo */
Ejemplo: Comentario de los atributos del TDA Tiempo
...
private:
int hora; /**< N umero de horas del objeto. Debe estar
entre 0 y 23 */
int minutos; /**< N umero de minutos del objeto. Debe estar
entre 0 y 59 */
};
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Ampliaci on: documentaci on de una clase con Doxygen
Existen comandos adicionales en Doxygen que permiten mejorar la
presentacion de la documentacion nal.
Comando \a. Escribe la palabra siguiente en un tipo de letra
especial. Se utiliza para resaltar nombres de parametros o
variables en el texto.
Comando \b. Escribe la palabra siguiente en negrita.
Comando \e. Escribe la palabra siguiente en cursiva.
Comando \n. Escribe un salto de lnea.
Comandos \\, \@, \$, \&, \#, \ <, \ >. Escriben el caracter
especial correspondiente.
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Constructores y Destructores
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Constructor de una clase
Motivacion
las variables tipo struct no se inicializan al declarar la variable
se necesitan inicializar campo a campo y sin seguridad de que
el usuario lo haga correctamente
un constructor resuelve este problema al declarar un objeto de
una clase
Constructor
Un constructor de una clase es un metodo miembro (p ublico) que
se utiliza para inicializar los datos de los objetos
tiene el mismo nombre que la clase en la que esta declarado
no devuelve nada, pero no es una funcion void
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Constructor de una clase
Ejemplo: constructor de la clase Tiempo
class Tiempo{
public:
Tiempo (){ // constructor
hora=0;
minutos=0;
}
void establecerHora (int , int );
void imprimir ();
private:
int hora;
int minutos;
};
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Constructor de una clase
Cuando se crea un objeto de una clase, un constructor es invocado
automaticamente
Ejemplo: constructor de la clase Tiempo
class Tiempo{
public:
Tiempo (){ hora=minutos=0; } // constructor
void imprimir ();
private:
int hora;
int minutos;
};
int main(){
Tiempo horacenar; // los datos se inicializan al declararlo
horacenar.imprimir(); }
0:0
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Constructor de una clase
Puede existir mas de un constructor (hay sobrecarga)
Ejemplo: clase Tiempo denida con varios constructores
class Tiempo{
public:
Tiempo (){// un constructor
hora=minutos=0;
}
Tiempo (int n, int m){ // otro constructor
hora=n; minutos=m;
}
void imprimir ();
private:
int hora;
int minutos;
};
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Constructor de una clase
Puede existir mas de un constructor (hay sobrecarga)
Ejemplo: clase Tiempo denida con varios constructores
int main(){
Tiempo horacenar; // se inicia con el constructor primero
horacenar.imprimir();
Tiempo horacomer (14,30); // se inicia con el segundo
horacomer.imprimir();
}
0:0
14:30
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Constructor de una clase
El constructor puede pasar parametros por defecto
Ejemplo: constructor con parametros por defecto
class Tiempo{
public:
Tiempo (int n=0,int m=0){// por defecto n=m=0
hora=n;
minutos=m;
}
void imprimir ();
private:
int hora;
int minutos;
};
int main(){
Tiempo horacenar, horadormir(23), horacomer(14,30);
horacenar.imprimir();
horadormir.imprimir();
horacomer.imprimir();
}
0:0
23:0
14:30
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Constructor de una clase
Un constructor debe asegurar que el usuario no inicializa de forma
incorrecta los datos
Ejemplo
Tiempo::Tiempo (int hr, int min){
hora= (hr < 24 && hr >= 0) ? hr : 0;
minutos= (min < 60 && min >= 0) ? min : 0;
}
int main(){
Tiempo horacenar (21,30), horadormir(25,76);
horacenar.imprimir();
horadormir.imprimir();
}
21:30
0:0
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Constructor de una clase
Comentarios
los datos miembro no pueden ser inicializados en la
declaracion de la clase
al menos debera implementarse el constructor basico
(constructor por defecto). Para controlar la creacion e
inicializacion
el compilador crea un constructor de ocio s olo si no se ha
denido ninguno
es particularmente util cuando ciertos campos requieren
reservar memoria
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Destructor de una clase
Destructor
El destructor de una clase es un metodo miembro (p ublico) que
ejecuta ciertos programas de terminacion antes de que el sistema
libere la memoria ocupada por el objeto
tiene el mismo nombre que la clase en la que esta declarado
precedido por ~
no devuelve nada, pero no es una funcion void
no tiene argumentos
Ejemplo: Destructor de la clase Tiempo
Tiempo::~Tiempo (){
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Destructor de una clase
CUIDADO!!!
No hay que hacer ninguna llamada al destructor. Cuando el objeto
sale de alcance se llama automaticamente al destructor
Comentarios
hay un unico destructor por clase (no admite sobrecarga)
si no se especica, el compilador proporciona un destructor de
ocio
con clases sencillas no se implementan destructores
su implementacion tiene sentido cuando el constructor ha
reservado memoria dinamicamente
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Destructor de una clase
Ejemplo: clase DNI
class DNI{
public:
DNI (){// un constructor
nombre=new (nothrow) char [30];
numero=0;
letra=0;
}
~DNI (){ // el destructor
delete [] nombre;
}
private:
char* nombre;
int numero;
char letra;
};
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Ejemplo mas completo: clase Polinomio
Archivo Polinomio.h
#ifndef Polinomio_H
#dene Polinomio_H
class Polinomio{
public:
Polinomio (int gradomaximo=10); // constructor
void PonCoeficiente (int , int );
double Evalua (double );
~Polinomio ();// destructor
private:
int* coeficientes;
int grado;
int maxgrado;
};
#endif
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Ejemplo mas completo: clase Polinomio
Archivo Polinomio.cpp (1)
#include <iostream>
#include <cmath>
#include Polinomio.h
using namespace std;
/*** constructor de la clase ***/
Polinomio::Polinomio (int gradomaximo){
maxgrado=gradomaximo;
grado = 0;
coeficientes = new (nothrow) int [maxgrado+1];
if (!coeficientes) {
cerr << Error: no hay memoria;
exit (1);
}
for (int i=0; i<= maxgrado; i++)
coeficientes[i] = 0;
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Ejemplo mas completo: clase Polinomio
Archivo Polinomio.cpp (2)
/*** establece el valor del coeciente de grado i ***/
void Polinomio::PonCoeficiente (int i, int valor){
if ( i<0 && i>maxgrado ) {
cerr << Error: grado incorrecto;
exit (1);
}
coeficientes[i] = valor;
if (i > grado)
grado = i;
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Ejemplo mas completo: clase Polinomio
Archivo Polinomio.cpp (3)
/*** evalua el polinomio en valor ***/
double Polinomio::Evalua (double valor){
double eval=0;
for (int i=1; i<=grado; i++)
if (coeficientes[i]!=0)
eval += (coeficientes[i]*pow(valor,grado));
return (eval);
}
/*** el destructor de la clase ***/
Polinomio::~Polinomio (){
delete [] coeficientes;
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Prioridad de ejecucion de constructores y destructores
Los constructores y destructores son llamados de forma automatica seg un
los objetos entran y salen de alcance
Llamada a los constructores
1
Objetos globales, antes de la ejecucion de cualquier funcion
2
Objetos locales a una funcion, cuando se hace una llamada a dicha
funcion. El orden dependera de donde este declarado
3
Objetos static , al ser declarados
Llamada de los destructores
1
Objetos globales, al nalizar el programa
2
Objetos locales a una funcion, al nalizar la ejecucion de la funcion
3
Objetos static , al nalizar el programa pero antes de los objetos
globales
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Prioridad de ejecucion de constructores y destructores
Regla general
Los destructores se ejecutan en orden inverso a la ejecucion de los
constructores respectivos
Ejemplo
class Orden{
public:
Orden (int j, string men){ // constructor
numero=j; msg=men;
cout << Constructor objeto
<< numero << : << msg << endl;
}
~Orden (){// destructor
cout << Destructor objeto
<< numero << : << msg << endl;
}
private:
int numero;
string msg;
};
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Prioridad de ejecucion de constructores y destructores
Ejemplo
#include <string>
#include <iostream>
using namespace std;
class Orden{ ... };
Orden Obj1(1,global);
void funcion ();
int main(){
cout << Entrando en main << endl;
Orden Obj2(2,local en main);
static Orden Obj3(3,static en main);
funcion ();
static Orden Obj6(6,static en main);
cout << Saliendo de main << endl;
}
void funcion (){
cout << Entrando en funcion << endl;
Orden Obj4(4,local en funcion);
static Orden Obj5(5,static en funcion);
cout << Saliendo de funcion << endl;
}
Salida
Constructor objeto 1: global
Ejecutando main
Constructor objeto 2: local en main
Constructor objeto 3: static en main
Entrando en funcion
Constructor objeto 4: local en funcion
Constructor objeto 5: static en funcion
Saliendo de funcion
Destructor objeto 4: local en funcion
Constructor objeto 6: static en main
Saliendo de main
Destructor objeto 2: local en main
Destructor objeto 6: static en main
Destructor objeto 5: static en funcion
Destructor objeto 3: static en main
Destructor objeto 1: global
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Constructor de copia
Motivacion
Frecuentemente queremos iniciar un objeto a partir de otro, p. e.,
int num=5; // inicializacion normal
int otro = num; // declaracion e inicializacion a partir de num
int otromas (num); //otra forma de inicializar a partir de num
Constructor de copia
Un constructor de copia inicializa un objeto a partir de otro
existente
si no se especica ninguno, el compilador proporciona uno de ocio
que copia bit a bit los datos miembro
este no es valido cuando el objeto requiere memoria dinamicamente
en general, es conveniente implementar un constructor de copia
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Constructor de copia
Ejemplo: constructor de copia de la clase Polinomio
Polinomio.h
#ifndef Polinomio_H
#dene Polinomio_H
class Polinomio{
public:
Polinomio (int gradomaximo=10); // constructor
Polinomio (const Polinomio & otro);// constructor de copia
void PonCoeficiente (int , int );
double Evalua (double );
void Imprime ();// saca por pantalla el polinomio
~Polinomio ();// destructor
private:
int* coeficientes;
int grado;
int maxgrado;
};
#endif
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Constructor de copia
Ejemplo: constructor de copia de la clase Polinomio
Polinomio.cpp
#include <iostream>
#include <cmath>
#include Polinomio.h
using namespace std;
/*** constructor de la clase ***/
Polinomio::Polinomio (int gradomaximo){...}
/*** constructor de copia de la clase ***/
Polinomio::Polinomio (const Polinomio & otro){
maxgrado=otro.maxgrado;
grado = otro.grado;
coeficientes = new (nothrow) int [maxgrado+1];// reserva OTRA zona de memoria para los coecientes
if (!coeficientes) {
cerr << Error: no hay memoria;
exit (1);
}
for (int i=0; i<= maxgrado; i++) // copia los coecientes
coeficientes[i] = otro.coeficientes[i];
}
/*** funcion Imprime ***/
void Imprime (){
for (int i=0;i<=grado;i++){
cout << coeficientes[i] << x << i << ;
}
/*** resto de metodos miembros ***/
void PonCoeficiente (int i, int valor){...}
double Evalua (double valor){...}
~Polinomio (){...}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Constructor de copia
Ejemplo: constructor de copia de la clase Polinomio
Principal.cpp
#include <iostream>
#include Polinomio.h
using namespace std;
int main(){
Polinomio p1 (2); // constructor normal
p1.PonCoeficiente(0,1);
p1.PonCoeficiente(1,1);
p1.PonCoeficiente(2,1);
Polinomio p2=p1;// Constructor de copia: p2 se inicializa como p1
Polinomio p3 (p1);// Constructor de copia: p3 se inicializa como p1
p1.Imprime();
p2.Imprime();
p3.Imprime();
}
1x0 1x1 1x2
1x0 1x1 1x2
1x0 1x1 1x2
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Constructor de copia
Pregunta importante
Que hubiera hecho un constructor de copia de ocio?
Respuesta
Le habra dado al puntero p2.coeficientes la misma direccion
de memoria de p1.coeficientes

Pila Heap
//
p1.coecientes
::
p2.coecientes
No podramos cambiar p2 sin cambiar p1!!!
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Constructor de copia
Cuando se usa un constructor de copia?
cuando se declara un objeto y se inicia a partir de otro de la
misma clase
cuando una funcion recibe un objeto por valor
cuando una funcion devuelve un objeto
el objeto devuelto se creo localmente en la funcion. Para poder
devolverse a la funcion que hace la llamada, debe copiarse
temporalmente a un objeto
Moraleja
Implementar un constructor de copia (por lo que pueda pasar).
Especialmente si se reserva memoria dinamicamente
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
El puntero this
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Denici on
Motivacion
class Elemento{
public:
int x;
int cuadrado (){ return x*x;}
}
int main(){
Elemento p1, p2;
p1.x=4; p2.x=5;
cout << p1.cuadrado() << << p2.cuadrado();
}
16 25
Pregunta
Las llamadas a la funcion cuadrado producen el resultado
correcto. Pero la funcion no tiene parametros como sabe las
variables que debe utilizar?
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Denici on
Respuesta
En realidad, s tiene un parametro (oculto). Un puntero (el puntero
this) que apunta a la direccion de memoria del objeto, y que es
pasado automaticamente por el compilador como argumento.
Puntero this
El puntero this es una variable predenida en todas las funciones
u operadores miembro de una clase. Contiene la direccion del
objeto concreto de la clase sobre el cual se esta aplicando la
funcion u operador miembro.
Palabra reservada
Para hacer uso de este puntero utilizamos la palabra this
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Denici on
Constructor de copia de la clase Polinomio
Polinomio :: Polinomio (const Polinomio & otro){
// usa los datos miembro empleando this, pero no se reere
// al objeto argumento (otro), this es un argumento implcito
// y se reere al objeto sobre el que aplicamos el constructor
this->maxgrado = otro.maxgrado;
this->grado = otro.grado;
this->coeficientes=new (nothrow) int [(this->maxgrado)+1];
if (!(this->coeficientes)) {
cerr << Error: no hay memoria;
exit (1);
}
for (int i=0; i<= this->maxgrado; i++)
(this->coeficientes)[i] = otro.coeficientes[i];
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Concatenaci on de funciones
El uso del puntero this permite la concatenaci on de funciones
Concatenaci on de funciones
Consiste en aplicar, en una declaracion, varias funciones miembro de una clase
a un objeto de dicha clase, por ejemplo,
Polinomio p;
p.ponCoeficiente(0,2).ponCoeficiente(1,1)
Implementaci on
Se consigue declarando que la funci on devuelva una referencia al objeto
Polinomio & ponCoeficiente (int i, int valor){
coeficientes[i]=valor;
return *this;
}
Como el operador . act ua de izquierda a derecha, primero se eval ua
p.ponCoeficiente(0,2) que regresa una referencia al objeto p y despues se
eval ua el equivalente a p.ponCoeficiente(1,1)
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Concatenaci on de funciones
Fichero Tiempo.h
#ifndef Tiempo_H
#dene Tiempo_H
class Tiempo{
public:
Tiempo (int n=0, int m=0);//constructor, por defecto 0:0
Tiempo & establecerHora (int ,int );//para establecer la hora completa
Tiempo & estHora (int ); // para establecer las horas
Tiempo & estMinuto (int );// para establecer los minutos
void imprimir (); // para imprimir la hora completa
private:
int hora;
int minutos;
};
#endif
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Concatenaci on de funciones
Fichero Tiempo.cpp
#include <iostream>
#include Tiempo.h
using namespace std;
/*** constructor ***/
Tiempo::Tiempo (int n, int m){
hora=(n < 24 && 0 <= n)? n : 0;
minutos=(m < 60 && 0 <= m)? m : 0;
}
/*** funcion que establece la hora completa ***/
Tiempo & Tiempo::establecerHora (int n, int m){
hora=(n < 24 && 0 <= n)? n : 0;
minutos=(m < 60 && 0 <= m)? m : 0;
return *this; // Permite la concatenacion
}
/*** funcion que establece el n umero de horas ***/
Tiempo & Tiempo::estHora (int n){
hora=(n < 24 && 0 <= n)? n : 0;
return *this; // Permite la concatenacion
}
/*** funcion que establece el n umero de minutos ***/
Tiempo & Tiempo::estMinuto (int m){
minutos=(m < 60 && 0 <= m)? m : 0;
return *this; // Permite la concatenacion
}
/*** funcion imprime la hora ***/
void Tiempo::imprimir (){
cout << ((hora < 10)? 0: ) << hora << :
<< ((minutos < 10)? 0: ) << minutos << endl;
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Concatenaci on de funciones
Fichero principal.cpp
#include Tiempo.h
int main(){
Tiempo horacenar;
horacenar.estHora(21).estMinuto(30);
horacenar.imprimir();
Tiempo horacomer;
horacomer.establecerHora(15,0).imprimir();
Tiempo horadesayunar;
horadesayunar.estHora(7).estMinuto(30).imprimir();
}
21:30
15:00
07:30
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicadores de datos y
metodos miembro
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicador const
Objetos const
El modicador const se usa para evitar poder modicar los datos
miembro de un objeto. Se utiliza a nadiendo const antes de la clase en
la declaracion del objeto
Ejemplo: const Tiempo p(12,30);
Nota
Obviamente, la propiedad de ser constante aparece despues de que el
constructor inicialice los datos miembro
Posible uso: paso por referencia constante
void cambiar (const Tiempo &p);
paso por referencia es mas eciente
evita la modicaci on de los datos miembro
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicador const
Intentar modicar los datos miembro de un objeto constante produce un
error de compilacion
Ejemplo
class clase{
public:
clase (int n){valor=n;};
void cambiar (int n){valor=n;};
int valor;
};
int main(){
const clase p (2);
p.valor=3;// cambiarlo directamente
p.cambiar(3);// cambiarlo a traves de una funcion miembro
}
Error: assignment of data-member clase::valor in read-only structure
Error: passing const clase as this argument of void clase::cambiar(int) discards qualiers
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicador const
El compilador deshabilita las llamadas a funciones miembro por objetos
constantes, aunque no modiquen los datos miembro
Ejemplo
class clase{
public:
clase (int n){valor=n;};
void mostrar () {cout << valor;};
int valor;
};
int main(){
const clase p (2);
p.mostrar();
}
Error: passing const clase as this argument of void clase::mostrar(int) discards qualiers
Pregunta
Es posible acceder a los datos de alguna manera? Porque si no...
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicador const
Respuesta
Es posible acceder a los datos miembro (pero no modicarlos!) mediante
funciones const
Declaracion de funciones const
Una funcion miembro se declara constante escribiendo la palabra
reservada const despues de la lista de parametros, tanto en el prototipo
como en la denicion
Ejemplo: void mostrar () const {...}
Ejemplo
class clase{
clase (int n){valor=n;};
void mostrar () const {cout << valor;};
int valor;
};
int main(){
const clase p (2);
p.mostrar();
}
2
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicador const
Comentarios sobre funciones const
no pueden modicar datos miembro (error de compilacion)
no pueden llamar a funciones no const (error de compilacion)
el constructor y el destructor no pueden declararse const
(error de compilacion), aunque s pueden modicar los datos
de un objeto constante, incluso llamando a funciones no
constantes. El objeto toma la propiedad de constante despues
de ejecutarse el constructor
se puede sobrecargar una funcion con una version constante y
otra no
es recomendable declarar constantes la funciones miembro que
no modican los datos
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicador const
Fichero Tiempo.h
#ifndef Tiempo_H
#dene Tiempo_H
class Tiempo{
public:
Tiempo (int n=0, int m=0);//constructor
void establecerHora (int ,int );//establece la hora
void imprimir1 (); // imprimir, version no constante
void imprimir2 () const; // imprimir, version constante
private:
int hora;
int minutos;
};
#endif
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicador const
Fichero Tiempo.cpp
#include <iostream>
#include Tiempo.h
using namespace std;
/*** constructor ***/
Tiempo::Tiempo (int n, int m){// hace uso de otra funci on para inicializar el objeto
establecerHora(n,m);
}
/*** funcion que establece la hora ***/
Tiempo & Tiempo::establecerHora (int n, int m){
hora=(n < 24 && 0 <= n)? n : 0;
minutos=(m < 60 && 0 <= m)? m : 0;
}
/*** funcion imprime la hora (no constante)***/
void Tiempo::imprimir1 (){
cout << ((hora < 10)? 0: ) << hora << :
<< ((minutos < 10)? 0: ) << minutos << endl;
}
/*** funcion imprime la hora (constante)***/
void Tiempo::imprimir2 () const {
cout << ((hora < 10)? 0: ) << hora << :
<< ((minutos < 10)? 0: ) << minutos << endl;
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicador const
Fichero principal.cpp
#include Tiempo.h
int main(){
Tiempo horacenar (21,30);// objeto no constante
const Tiempo horacomer (15,0);//objeto const, constructor no const
horacenar.imprimir1();// objeto no const, funci on no const > OK
horacenar.imprimir2();// objeto no const, funci on const > OK
horacomer.imprimir1();// objeto const, funci on no const > Error
horacomer.imprimir2();// objeto const, funci on const > OK
}
Error: passing const Tiempo as this argument of void
Tiempo::imprimir1() discards qualiers
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicador const
Un ejemplo de funciones que se suelen declarar const son las
llamadas funciones get. Son funciones que devuelven el valor de un
dato miembro (pero no lo modican).
Clase Tiempo
class Tiempo{
public:
Tiempo (int n=0, int m=0);//constructor
void get_hora() const {return hora;};
// funcion get para el dato hora
void get_minutos () const {return minutos;};
// funcion get para el dato minutos
private:
int hora;
int minutos;
};
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicador const
Contrario a esto son las llamadas funciones set (establecer). Son
funciones que se utilizan para permitir la modicacion de un dato
miembro. Obviamente, no tiene sentido declararlas const
Clase Tiempo
class Tiempo{
public:
Tiempo (int n=0, int m=0);//constructor
void set_hora (int n) {hora=n;};
void set_minutos (int m) {minutos=m;};
void get_hora() const {return hora;};
void get_minutos () const {return minutos;};
private:
int hora;
int minutos;
};
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicador const
Datos miembro constantes
Existe la posibilidad de declarar algunos datos miembro de tipo
constante. Estos no podran ser modicados despues de su inicializacion
por el constructor
Fichero Persona.h
#ifndef Persona_H
#def Persona_H
class Persona{
public:
Persona (string n, int m);//constructor
void incremento ();//incrementa un anio
void imprimir (); // imprimir nombre y edad
private:
const string nombre; // dato miembro constante
int edad;
};
#endif
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicador const
Iniciacion de datos miembro constantes
La inicializacion de datos miembros constantes la realiza el
constructor con la lista de iniciacion o iniciadores de miembros
Fichero Persona.cpp
#include <iostream>
#include Persona.h
using namespace std;
/*** constructor ***/
Persona::Persona (string n, int m)
: nombre (n), // inicializador de miembros, : despues de argumentos
edad (m)// los no constantes pueden inicializarse tambien as (opcional)
{ }// cuerpo del constructor
/*** funcion que a nade un anio ***/
void Persona::incremento (){
edad++;
}
/*** funcion que imprime ***/
void Persona::imprimir1 (){
cout << nombre<< tiene << edad << anios << endl;
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicador const
CUIDADO!!!
Los datos miembro constantes no se pueden inicializar en la declaracion
de la clase. Tampoco dentro del cuerpo de denicion del constructor
Ejemplo
class Persona{
public:
Persona (string n, int m);
void incremento ();
void imprimir ();
private:
const string nombre=Manolito; // Error
int & edad=34;// Error, referencias tambien con listas de iniciacion
};
Persona::Persona(string n, int m){
nombre=n;// Error
edad=m;// Error
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicador const
Tambien es obligatoria, con iniciadores de miembros, la iniciacion de un
objeto de otra clase que sea miembro de la clase considerada.
Ejemplo
class Otra{
public:
Otra (Persona n, int m);
private:
Persona sujeto;
int sueldo;
};
Otra::Otra(Persona n, int m)
: sujeto (n)
{
sueldo=m;
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicador static
Problema
Cada objeto de una clase reserva memoria para los datos miembro
de la clase. Sin embargo, si existe un dato miembro cuyo valor
debe ser com un a todos los objetos
se esta gastando memoria innecesariamente
cuando cambia el valor, hay que actualizar todos los objetos
de uno en uno
Solucion
Declarar dicho dato como static
class Punto2D{
int x;
static int y;
};
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicador static
Datos miembro static
se declaran anteponiendo static al tipo de dato
existe una copia para todos los objetos
existen aunque no haya objetos (se reserva memoria en la
declaracion)
pueden ser p ublicos o privados (o protected)
deben iniciarse en el chero de denicion de la clase (.cpp),
sin especicarse la palabra reservada static
solo pueden inicializarse una vez
tipo dato clase::identificador = valor;
acceso a los datos estaticos p ublicos:
clase::identificador (recomendado)
objeto.identificador si existe al menos un objeto
acceso a datos estaticos privados: mediante funciones static
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicador static
Ejemplo: contar n umero de objetos creados
#ifndef Animal_H
#dene Animal_H
class Animal{
public:
Animal (string nom, int p=0, bool t=false); //constructor
~Animal ();// destructor
private:
string nombre;
int patas;
bool terrestre;
public:
static int num_animales;
};
#endif
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicador static
Fichero Animal.cpp
#include Animal.h
/*** inicializar datos estaticos ***/
int Animal::num_animales = 0;
/*** constructor ***/
Animal::Animal (string nom, int p, bool t){
nombre=nom;
patas=p;
terrestre=t;
num_animales ++;
}
/*** destructor ***/
Animal::~Animal (){
num_animales --;
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicador static
Fichero principal.cpp
#include <iostream>
#include Animal.h
using namespace std;
int main(){
// aunque no exista ning un objeto, s existe num animales!!!!
cout << numero de animales = << Animal::num_animales << endl;
Animal gato(gato,4,true);
cout << numero de animales = << gato.num_animales << endl;
Animal * ptr_delfin;
ptr_delfin=new (nothrow) Animal (deln,0,false);
cout << numero de animales = << ptr_delfin->num_animales << endl;
Animal arania(arania,8,true);
cout << numero de animales = << Animal::num_animales << endl;
delete ptr_delfin;
cout << numero de animales = << gato.num_animales << endl;
}
numero de animales = 0
numero de animales = 1
numero de animales = 2
numero de animales = 3
numero de animales = 2
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicador static
Funciones miembro static
se declaran anteponiendo static al tipo de dato de retorno
no act uan sobre ning un objeto concreto de la clase
no pueden hacer llamadas a funciones ni a datos miembro NO
static
el modicador static solo aparece en la declaracion, no en la
denicion
dos formas de invocarlas:
clase::funcion_static
objeto.funcion_static, solo cuando exista un objeto de la
clase
no se puede utilizar el puntero this, ya que hace referencia a
un objeto concreto de la clase
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicador static
Ejemplo: contar n umero de objetos creados
#ifndef Animal_H
#dene Animal_H
class Animal{
public:
Animal (string nom, int p=0, bool t=false); //constructor
static void imprimir(); // funcion estatica
~Animal ();// destructor
private:
string nombre;
int patas;
bool terrestre;
static int num_animales;
};
#endif
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicador static
Fichero Animal.cpp
#include Animal.h
/*** inicializar datos estaticos ***/
int Animal::num_animales = 0;
/*** constructor ***/
Animal::Animal (string nom, int p, bool t){
nombre=nom;
patas=p;
terrestre=t;
num_animales ++;
}
/*** funcion estatica imprimir***/
void Animal::imprimir(){
cout<<numero de animales =<< num_animales <<endl;
} // num animales es de tipo static, se puede utilizar aqu
/*** destructor ***/
Animal::~Animal (){
num_animales --;
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Modicador static
Fichero principal.cpp
#include <iostream>
#include Animal.h
using namespace std;
int main(){
// aunque no exista ning un objeto, se puede invocar imprimir!!!
Animal::imprimir();
Animal gato(gato,4,true);
gato.imprimir();
Animal * ptr_delfin;
ptr_delfin=new (nothrow) Animal (deln,0,false);
ptr_delfin->imprimir();
Animal arania(arania,8,true);
arania.imprimir();
delete ptr_delfin;
gato.imprimir();
}
numero de animales = 0
numero de animales = 1
numero de animales = 2
numero de animales = 3
numero de animales = 2
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Funciones friend
Motivacion
En ciertas ocasiones (p.e, sobrecarga de operadores) necesitamos
que funciones no miembro puedan acceder a los datos miembro
privados de una clase
Modicador friend
Especicar una funcion como friend para una clase, permite a
dicha funcion acceder a los datos privados de la clase
se deben declarar en la denicion de la clase anteponiendo
friend al tipo de retorno (pero no en la denicion)
las etiquetas public, private o protected no le afectan (ya
que no es una funcion miembro)
se puede declarar en cualquier parte de la denicion de la
clase (normalmente se ponen al principio)
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Funciones friend
Ejemplo: funcion amiga a una clase
class Caja{
friend int aumentar (int );
public:
Caja ();
imprimir (int , int );
colorear ();
private:
int x;
}
Ejemplo: clase amiga a otra clase
class Otra{
friend class Caja;// todas las funciones de Caja son amigas a Otra
public:
Otra ();
private:
string nombre;
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Funciones friend
Nota
Hay que tener cuidado al declarar funciones friend ya que se pierde
la privacidad de los datos miembro y se permite su manipulacion
Comentarios
aunque no sean funciones miembro, se suelen implementar en
el mismo chero que estas (Clase.cpp)
es posible declarar como friend una funcion sobrecargada
la amistad no es simetrica ni transitiva
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Funciones inline
Funciones inline
La etiqueta inline , precediendo al tipo de dato de retorno, sugiere
al compilador que copie el codigo de la funcion y lo reemplace por
cada llamada a la funcion
Ventaja: menor tiempo de ejecucion
Desventaja: mayor tama no del archivo ejecutable
Ejemplo
class clase{
int devolver();
int x;
};
inline int devolver(){return x;}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Funciones inline
Si una funcion se declara y se dene en la propia clase, el
compilador la considera inline aunque no se haya indicado
explcitamente esa etiqueta
Ejemplo
class clase{
inline int devolver(){return x;};
// devolver pasa a ser automaticamente inline
int x;
};
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga de operadores
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Motivaci on
Suma de polinomios
En la clase Polinomio , parece logico denir una funcion suma que
devuelva la suma de dos objetos suma(p1,p2). Sin embargo, la
suma de polinomios esta muy relacionada con la suma de n umeros
enteros y nos gustara poder escribirlo p1+p2
Sobrecarga de operadores
C++ permite sobrecargar la mayora de los operadores disponibles
para que operen con los tipos de datos denidos por el usuario.
Esto:
proporciona expresiones concisas y conocidas al usuario
por tanto, programa mas faciles de escribir y leer
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Implementaci on
Operadores que pueden sobrecargarse
+ - * % ^ & | / !
= < > += -= *= /= %= ^=
&= |= << >> >>= <<= == != <=
>= && || ++ -- ->* , -> []
() new delete new[] delete[]
Operadores que NO pueden sobrecargarse
. .* :: ?: sizeof
CUIDADO!!!
NO ES POSIBLE CREAR NUEVOS OPERADORES
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Implementaci on
Limitaciones
no puede modicarse la gramatica del operador original
(n umero operandos, precedencia y asociatividad)
un operando, al menos, debe ser un objeto de la clase en la
que se dene el operador. As el programador no puede
modicar los operadores existentes
Implementacion
la declaracion se realiza de la siguiente manera
tipo retorno operator simbolo_operador (argumentos );
se dene como una funcion normal
Ejemplo
Polinomio & operator + (Polinomio p);
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Implementaci on
Realizacion de la sobrecarga
La sobrecarga NO es automatica, deben denirse las funciones
explcitamente. Estas pueden declararse como:
funciones miembro
el primer argumento es el puntero this (argumento implcito)
en operadores unarios
en operadores binarios que modican el primer operando
funciones no miembro amigas (friend )
se deben listar explcitamente los argumentos
cuando el primer operando no es un objeto de la clase (p.e,<<)
si act ua sobre varios objetos sin modicarlos
funciones no miembro no amigas (no es lo normal)
En cualquier caso, NO pueden ser funciones static
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Implementaci on
Comentarios
sobrecargar un operador no sobrecarga los operadores
relacionados, p.e., sobrecargar + no sobrecarga +=
los operadores con versiones unaria y binaria pueden
sobrecargarse en ambas versiones
los operadores sobrecargados deberan llevar a cabo la misma
funcion (o muy parecida)
En cualquier caso, no es posible crear operadores nuevos
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador =
Si no se sobrecarga, es posible utilizarlo y se realiza una copia
exacta (bit a bit) de los datos miembro
Ejemplo
class Punto2D{
public:
int x;
int y;
};
int main(){
Punto2D uno, otro;
uno.x=2; uno.y=3;
otro=uno; // copio cada dato miembro
cout << otro.x << << otro.y;
}
2 3
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador =
CUIDADO!!!
Si hay reserva de memoria dinamica, y no se sobrecarga, puede haber problemas
Ejemplo con la clase Polinomio
class Polinomio{...};
p1=p2;

Pila Heap
//
p1.coecientes
::
p2.coecientes
referencian a la misma zona de memoria!!!
Moraleja
Si los objetos de la clase reservan memoria dinamicamente, se debera
sobrecargar el operador de asignaci on
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador =
Declaracion del operador =
clase & operator = (const clase &origen);
Nota: el primer argumento es implcito (el objeto que va a ser modicado)
Polinomio.h
#ifndef Polinomio_H
#dene Polinomio_H
class Polinomio{
public:
Polinomio (int gradomaximo=10); // constructor
Polinomio (const Polinomio & otro);// constructor de copia
void PonCoeficiente (int , int );
double Evalua (double );
void Imprime ();// saca por pantalla el polinomio
Polinomio & operator = (const Polinomio &otro);// operador =
~Polinomio ();// destructor
private:
int* coeficientes;
int grado;
int maxgrado;
};
#endif
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador =
Polinomio.cpp (1)
#include <iostream>
#include <cmath>
#include Polinomio.h
using namespace std;
/*** constructor de la clase ***/
Polinomio::Polinomio (int gradomaximo){
maxgrado=gradomaximo;
grado = 0;
coeficientes = new (nothrow) int [maxgrado+1];
if (!coeficientes) {
cerr << Error: no hay memoria;
exit (1);
}
for (int i=0; i<= maxgrado; i++)
coeficientes[i] = 0;
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador =
Polinomio.cpp (2)
/*** constructor de copia de la clase ***/
Polinomio::Polinomio (const Polinomio & otro){
maxgrado=otro.maxgrado;
grado = otro.grado;
coeficientes = new (nothrow) int [maxgrado+1];
if (!coeficientes) {
cerr << Error: no hay memoria;
exit (1);
}
for (int i=0; i<= maxgrado; i++) // copia los coecientes
coeficientes[i] = otro.coeficientes[i];
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador =
Polinomio.cpp (3)
/*** Funci on que asigna coecientes ***/
void Polinomio::PonCoeficiente (int i, int valor){
if ( i<0 && i>maxgrado ) {
cerr << Error: grado incorrecto;
exit (1);
}
coeficientes[i] = valor;
if (i > grado)
grado = i;
}
/*** evalua el polinomio en valor ***/
double Polinomio::Evalua (double valor){
double eval=0;
for (int i=1; i<=grado; i++)
if (coeficientes[i]!=0)
eval += (coeficientes[i]*pow(valor,grado));
return (eval);
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador =
Polinomio.cpp (4)
/*** funcion Imprime ***/
void Polinomio::Imprime (){
if (coeficientes[0] != 0)
cout << coeficientes[0] << ;
for (int i=1; i<=grado;i++)
if (coeficientes[i] != 0)
cout << coeficientes[i] << x << i << ;
cout << endl;
}
/*** el destructor de la clase ***/
Polinomio::~Polinomio (){
delete [] coeficientes;
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador =
Polinomio.cpp (5)
/*** sobrecarga operador = ***/
Polinomio & Polinomio ::operator = (const Polinomio &otro){
if (this != &otro) {// para evitar si son iguales
maxgrado = otro.maxgrado;// copia del campo maxgrado
grado = otro.grado;// copia del campo grado
delete [] coeficientes;// eliminar los coecientes antiguos
coeficientes = new (nothrow) int [maxgrado+1];// reserva
if (!coeficientes) { // nuevos coecientes
cerr << Error: no hay memoria;
exit (1);
}
for (int i=0; i<= maxgrado; i++) // copia los coecientes
coeficientes[i] = otro.coeficientes[i];
}
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador =

situacion original
Pila Heap
//
this.coecientes
//
otro.coecientes
0 1 2 3
1 0 0 0 1

delete [] coecientes
Pila Heap
//
this.coecientes
//
otro.coecientes
1 0 0 0 1

coecientes=new int []
Pila Heap
..
this.coecientes
//
otro.coecientes
1 0 0 0 1

bucle for (copiar)


Pila Heap
..
this.coecientes
//
otro.coecientes
1 0 0 0 1
1 0 0 0 1
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador =
CUIDADO!!!
Es necesario a nadir
delete [] coeficientes;
en la denici on del operador =, si no, se pierde memoria

situacion original
Pila Heap
//
this.coecientes
//
otro.coecientes
0 1 2 3
1 0 0 0 1

p1=p2 (sin delete)


Pila Heap
..
this.coecientes
//
otro.coecientes
0 1 2 3
1 0 0 0 1
1 0 0 0 1
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador =
CUIDADO!!!
Es necesario vericar primero si
this!=otro
para no producir errores

situacion original
Pila Heap
//
this.coecientes
otro.coecientes
0 1 2 3

delete [] coecientes
Pila Heap
//
this.coecientes
otro.coecientes
se pierde informaci on
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador =
principal.cpp
#include Polinomio.h
int main(){
Polinomio p1 (3);
p1.PonCoeficiente (0,4);
p1.PonCoeficiente (1,2);
p1.PonCoeficiente (2,0);
p1.PonCoeficiente (3,1);
p1.Imprime();
Polinomio p2 (4);
p2.PonCoeficiente (0,1);
p2.PonCoeficiente (4,1);
p1=p2;
p1.Imprime();
}
4 2x1 1x3
1 1x4
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador =
El operador = y el constructor de copia (y el constructor normal)
tienen declaraciones y deniciones parecidas, excepto:
no tiene sentido que el constructor compruebe si this!=otro,
ya que esta creando el objeto
no tiene sentido que libere memoria, puesto inicialmente no
hay reserva (el constructor la reserva)
Repetir codigo produce programas difcilmente mantenibles
Nuevas funciones miembro
Declaramos nuevas funciones miembro privadas:
void reservar (int n); //reserva memoria para coecientes
void liberar (); //libera memoria de coecientes
void copiar (const Polinomio &otro);//copia los coecientes
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador =
Polinomio.h
#ifndef Polinomio_H
#dene Polinomio_H
class Polinomio{
public:
Polinomio (int gradomaximo=10); // constructor
Polinomio (const Polinomio & otro);// constructor de copia
void PonCoeficiente (int , int );
double Evalua (double );
void Imprime ();// saca por pantalla el polinomio
Polinomio & operator = (const Polinomio &otro);// operador =
~Polinomio ();// destructor
private:
void reservar (int n); //reserva memoria para coecientes
void liberar (); //libera memoria de coecientes
void copiar (const Polinomio &otro);//copia los coecientes
int* coeficientes;
int grado;
int maxgrado;
};
#endif
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador =
Nuevas funciones, en Polinomio.cpp
/*** funcion reservar ***/
void Polinomio::reservar (int n){
coeficientes = new (nothrow) int [n];
if (!coeficientes) {
cerr << Error: no hay memoria;
exit (1);
}
}
/*** funcion liberar ***/
void Polinomio::liberar (){
delete [] coeficientes;
}
/*** funcion copiar ***/
void Polinomio::copiar (const Polinomio &otro){
maxgrado = otro.maxgrado;
grado = otro.grado;
reservar (maxgrado+1);
for (int i=0; i<= maxgrado; i++)
coeficientes[i] = otro.coeficientes[i];
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador =
Funciones que cambian, en Polinomio.cpp
/*** constructor por defecto ***/
Polinomio::Polinomio (int n){
maxgrado=n;
grado=0;
reservar (maxgrado+1);
for (int i=0;i<=maxgrado;i++)
coeficientes[i]=0;
}
/*** constructor de copia ***/
Polinomio::Polinomio (const Polinomio &otro){
copiar (otro);
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador =
Funciones que cambian, en Polinomio.cpp
/*** operador = ***/
Polinomio & Polinomio::operator = (const Polinomio &otro){
if (this!=otro)
liberar();
copiar(otro);
}
return *this;
}
/*** destructor ***/
Polinomio::~Polinomio (){
liberar ();
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador []
Motivacion
El acceso normal a los coecientes de un objeto Polinomio
complica la escritura y lectura de codigo
p1.PonCoeficiente (0,4)
if (p1.coeficientes[i]!=0)
Posible solucion
Sobrecargar el operador [] para acceder a los coecientes como a
los elementos de un vector
p1[0]=4
if (p1[i]!=0)
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador []
Declaracion del operador []
int & operator [] (const int indice);
es un operador binario, el primer argumento es el objeto de la
clase (implcito)
el primer argumento se modica
se declara como funcion miembro de la clase
se devuelve una referencia para permitir usar p1[i] a derecha
e izquierda de una asignacion
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador []
Polinomio.h
#ifndef Polinomio_H
#dene Polinomio_H
class Polinomio{
public:
Polinomio (int gradomaximo=10);
Polinomio (const Polinomio & otro);
void PonCoeficiente (int , int );
double Evalua (double );
void Imprime ();
Polinomio & operator = (const Polinomio &otro);
int & operator [] (const int indice); // operador []
~Polinomio ();
private:
void reservar (int n);
void liberar ();
void copiar (const Polinomio &otro);
int* coeficientes;
int grado;
int maxgrado;
};
#endif
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador []
Operador [] en Polinomio.cpp
/*** sobrecarga del operador [] ***/
int & Polinomio::operator [] (const int indice){
if ( (indice<0) && (indice>maxgrado) ) {
cerr << Error: grado incorrecto;
exit (1);
}
if (indice > grado)
grado = indice; // CUIDADO!!!
return (coeficientes[indice]);
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador []
Problema
El operador [] modica el grado
Ejemplo
Polinomio p1 (10); // inicia p1 y p1.grado=0
p1[0]=3; // p1.grado=0
p1[1]=2; // p1.grado=1
p1[4]=1; // p1.grado=3
p1[7]=0; // p1.grado=6!!!!!
cout << p1[9]; // p1.grado=8!!!!
Una solucion
Normalmente, el dato miembro grado no es relevante. Lo
eliminamos y denimos una funcion lo que calcule cuando sea
necesario
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador []
Polinomio.h
#ifndef Polinomio_H
#dene Polinomio_H
class Polinomio{
public:
Polinomio (int gradomaximo=10);
Polinomio (const Polinomio & otro);
void PonCoeficiente (int , int );
double Evalua (double );
void Imprime () const ;
Polinomio & operator = (const Polinomio &otro);
int & Polinomio::operator [] (const int indice);
~Polinomio ();
private:
void reservar (int n);
void liberar ();
void copiar (const Polinomio &otro);
int grado () const ; // funcion que calcula el grado
int* coeficientes;
int maxgrado;
};
#endif
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador []
Polinomio.cpp (1)
#include <iostream>
#include <cmath>
#include Polinomio.h
using namespace std;
/*** constructor por defecto ***/
Polinomio::Polinomio (int n){
maxgrado=n;
reservar (maxgrado+1);
for (int i=0;i<=maxgrado;i++)
coeficientes[i]=0;
}
/*** constructor de copia ***/
Polinomio::Polinomio (const Polinomio &otro){
copiar (otro);
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador []
Polinomio.cpp (2)
/*** funcion para establecer coecientes ***/
void Polinomio::PonCoeficiente (int i, int valor){
if ( i<0 && i>maxgrado ) {
cerr << Error: grado incorrecto;
exit (1);
}
coeficientes[i] = valor;
}
/*** evalua el polinomio en valor ***/
double Polinomio::Evalua (double valor){
double eval=0;
for (int i=1; i<=grado(); i++)
if (coeficientes[i]!=0)
eval += (coeficientes[i]*pow(valor,grado()));
return (eval);
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador []
Polinomio.cpp (3)
/*** funcion Imprime ***/
void Polinomio::Imprime () const {
if (coeficientes[0] != 0)
cout << coeficientes[0] << ;
for (int i=1; i<=grado();i++)
if (coeficientes[i] != 0)
cout << coeficientes[i] << x << i << ;
cout << endl;
}
/*** operador = ***/
Polinomio & Polinomio::operator = (const Polinomio &otro){
if (this != &otro) {
liberar();
copiar(otro);
}
return *this;
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador []
Polinomio.cpp (4)
/*** sobrecarga del operador [] ***/
int & Polinomio::operator [] (const int indice){
if ( (indice<0) && (indice>maxgrado) ) {
cerr << Error: grado incorrecto;
exit (1);
}
return (coeficientes[indice]);
}
/*** destructor ***/
Polinomio::~Polinomio (){
liberar ();
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador []
Polinomio.cpp (5)
/*** funcion reservar ***/
void Polinomio::reservar (int n){
coeficientes = new (nothrow) int [n];
if (!coeficientes) {
cerr << Error: no hay memoria;
exit (1);
}
}
/*** funcion liberar ***/
void Polinomio::liberar (){
delete [] coeficientes;
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga del operador []
Polinomio.cpp (6)
/*** funcion copiar ***/
void Polinomio::copiar (const Polinomio &otro){
maxgrado = otro.maxgrado;
reservar (maxgrado+1);
for (int i=0; i<= maxgrado; i++)
coeficientes[i] = otro.coeficientes[i];
}
/*** funcion que calcula el grado ***/
int Polinomio::grado () const {
int i=maxgrado;
bool sigo = true;
for (i=maxgrado+1; (i>=0) && sigo ; i--)
if (coeficientes[i] != 0)
sigo = false;
return i;
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga de operadores aritmeticos
Motivacion
Para realizar operaciones en el anillo de los polinomios,
manteniendo los operadores aritmeticos, sobrecargamos + y *
Declaracion del operador +
Es un operador binario que no modica ninguno de los argumentos
como funcion miembro (primer argumento implcito)
Polinomio operator + (const Polinomio & p2);
como funcion friend
friend Polinomio operator + (const Polinomio &p1,
const Polinomio &p2);
Ejemplo de uso
p3=p1+p2;// que signica p3=p1.operator+(p2);
// o bien p3.operator=(p1.operator+(p2));
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga de operadores aritmeticos
Operador +, en Polinomio.cpp
/*** operador sobrecargado + ***/
Polinomio Polinomio::operator + (const Polinomio & p2){
int mayor;
if ( maxgrado > p2.maxgrado )
mayor = maxgrado;
else
mayor = p2.maxgrado;
Polinomio p3 (mayor);
for (int i=0; i<= p3.maxgrado ; i++)
p3.coeficientes[i]=coeficientes[i] +
p2.coeficientes[i];
return p3;
}
CUIDADO: Esta funcion comete fallos!!!
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga de operadores aritmeticos
Ejemplo, principal.cpp
#include Polinomio.h
int main(){
Polinomio p1 (3)
p1[0]=4 ; p1[1]=2 ; p1[2]=0 ; p1[3]=1;
Polinomio p2 (4)
p2[0]=1 ; p2[4]=1;
Polinomio p3=p1+p2;
p1.Imprime();
p2.Imprime();
p3.Imprime();
}
4 2x1 1x3
1 1x4
5 2x1 1x3 196613x4
Ejercicio
Implementar el operador de forma correcta
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga de operadores aritmeticos
Posible soluci on
/*** operador sobrecargado + ***/
Polinomio Polinomio::operator + (const Polinomio & p2){
int mayor, menor;
if ( maxgrado > p2.maxgrado ){
mayor = maxgrado; menor=p2.maxgrado;}
else{
mayor = p2.maxgrado; menor=maxgrado;}
Polinomio p3 (mayor);
for (int i=0; i<= menor ; i++)
p3.coeficientes[i]=coeficientes[i] + p2.coeficientes[i];
if (mayor==maxgrado)
for(int i=menor+1; i<= mayor; i++)
p3.coeficientes[i] = coeficientes[i];
if (mayor==p2.maxgrado)
for(int i=menor+1; i<= mayor; i++)
p3.coeficientes[i] = p2.coeficientes[i];
return p3;
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga de operadores aritmeticos
Motivacion
El operador * necesita sobrecargarse con tres versiones:
p=p1*p2, esto es, Polinomio * Polinomio
p=p1*3, esto es, Polinomio * int
p=3*p1, esto es, int * Polinomio
Nota
Otra solucion es embeber los enteros en el algebra de los
polinomios y no denir enteros para multiplicarlos, sino polinomios
constantes
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga de operadores aritmeticos
Problema
El primer operando de la tercera version del operador no es un
objeto de la clase
Un operador en el que no pueda asegurarse que el primer
argumento sea siempre un objeto de la clase no se
implementara como una funcion miembro
Solucion
Implementar la tercera version como una funcion friend
Nota
Si alguna version de un operador debe implementarse con una
funcion friend, se recomienda sobrecargar todas como friend
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga de operadores aritmeticos
Polinomio.h (1)
#ifndef Polinomio_H
#dene Polinomio_H
class Polinomio{
friend Polinomio operator * (const Polinomio & ,const Polinomio &);
friend Polinomio operator * (const int ,const Polinomio &);
friend Polinomio operator * (const Polinomio &,const int &);
public:
Polinomio (int gradomaximo=10);
Polinomio (const Polinomio & otro);
void PonCoeficiente (int , int );
double Evalua (double );
void Imprime () const ;
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga de operadores aritmeticos
Polinomio.h (2)
Polinomio & operator = (const Polinomio &otro);
int & Polinomio::operator [] (const int indice);
~Polinomio ();
private:
void reservar (int n);
void liberar ();
void copiar (const Polinomio &otro);
int grado () const ; // funcion que calcula el grado
int* coeficientes;
int maxgrado;
};
#endif
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga de operadores aritmeticos
Sobrecarga operador *, en Polinomio.cpp (1)
/*** operador * (version int*Polinomio) ***/
Polinomio operator * (const int n, const Polinomio & p1){
Polinomio p2 (p1.maxgrado);
for (int i=0; i< p2.maxgrado; i++)
p2.coeficientes[i] = n * p1.coeficientes[i];
return p2;
}
/*** operador * (version Polinomio*int) ***/
Polinomio operator * (const Polinomio & p1, const int n){
return (n * p1); // aprovechamos la conmutatividad
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga de operadores aritmeticos
Sobrecarga operador *, en Polinomio.cpp (2)
/*** operador * (version Polinomio*Polinomio) ***/
Polinomio operator * (const Polinomio & p1, const Polinomio & p2){
Polinomio p3 (p1.maxgrado * p2.maxgrado);
for (int i=0; i< (p1.maxgrado * p2.maxgrado) ; i++)
for (int j=0; j<= i; j++)
p3.coeficientes[i] += p1.coeficientes[j]
* p2.coeficientes[i-j]
return p3;
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga de operadores << y >>
Motivacion
Se quiere mostrar e introducir los datos de tipo Polinomio
mediante el operador de extraccion << e insercion >> de ujo
Problemas que encontramos
son operadores binarios donde el primer argumento NO es un
objeto de la clase Polinomio
utilizaremos como primer operando cin o cout, que son
objetos de la clase istream y ostream, respectivamente
no podemos a nadir funciones miembro a istream o ostream
deben denirse como funciones friend a la clase Polinomio
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga de operadores << y >>
Polinomio.h (1)
#ifndef Polinomio_H
#dene Polinomio_H
class Polinomio{
friend Polinomio operator * (const Polinomio & ,const Polinomio &);
friend Polinomio operator * (const int ,const Polinomio &);
friend Polinomio operator * (const Polinomio &,const int &);
friend ostream & operator << (ostream &, const Polinomio &);
friend istream & operator >> (istream &, const Polinomio &);
public:
Polinomio (int gradomaximo=10);
Polinomio (const Polinomio & otro);
void PonCoeficiente (int , int );
double Evalua (double );
// se elimina la funcion Imprime
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga de operadores << y >>
Polinomio.h (2)
Polinomio & operator = (const Polinomio &otro);
int & Polinomio::operator [] (const int indice);
~Polinomio ();
private:
void reservar (int n);
void liberar ();
void copiar (const Polinomio &otro);
int grado () const ; // funcion que calcula el grado
int* coeficientes;
int maxgrado;
};
#endif
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga de operadores << y >>
Operador <<, en Polinomio.cpp
/*** operador << ***/
ostream & operator<< (ostream &salida,const Polinomio &p){
if (p.coeficientes[0] != 0)
salida << p.coeficientes[0] << ;
for (int i=1; i<=p.grado();i++)
if (p.coeficientes[i] != 0)
salida << p.coeficientes[i]<< x << i<< ;
salida << endl;
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga de operadores << y >>
Operador >>, en Polinomio.cpp
/*** operador >> ***/
istream & operator>> (istream &in,const Polinomio &p){
int valor_grado, valor_coef;
cout <<Introd. grado del polinomio (<=<<p.maxgrado<<): ;
in >> valor_grado;
for (int i=0; i<=valor_grado; i++){
cout <<Introd. coeciente de grado << i << : ;
in >> valor_coef;
p.coeficientes[i] = valor_coef;
}
return (in);
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga de operadores << y >>
principal.cpp
#include "Polinomio.h"
int main(){
Polinomio p (3);
cin >> p;
cout << p;
}
Introd. grado del polinomio (<=3): 3
Introd. coeciente de grado 0: 1
Introd. coeciente de grado 1: 3
Introd. coeciente de grado 2: 0
Introd. coeciente de grado 3: 2
1 3x1 2x3
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga de operadores ++ y
Problema
El operador ++ (unario) tiene una version prejo y posjo, ambas
con la misma gramatica como distingue el compilador entre
ambas?
Solucion
Una de ellas tiene un argumento cticio de tipo int que no
afecta al resultado
Declaracion como funciones miembro
clase & operator ++ ( ); // preincremento
clase & operator ++ (int ); // posincremento
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga de operadores ++ y
Fichero Tiempo.h
#ifndef Tiempo_H
#dene Tiempo_H
class Tiempo{
friend ostream & operator << (ostream &, const Tiempo &);
public:
Tiempo (int n=0, int m=0);
void establecerHora (int ,int );
Tiempo & operator ++ (); // preincremento
Tiempo operator ++ (int ); // posincremento
private:
void incrementar ();// funcion auxiliar de incremento
int hora;
int minutos;
};
#endif
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga de operadores ++ y
Fichero Tiempo.cpp (1)
#include <iostream>
#include Tiempo.h
using namespace std;
/*** constructor ***/
Tiempo::Tiempo (int n, int m){// hace uso de otra funcion
establecerHora(n,m);
}
/*** funcion que establece la hora ***/
void Tiempo::establecerHora (int n, int m){
hora=(n < 24 && 0 <= n)? n : 0;
minutos=(m < 60 && 0 <= m)? m : 0;
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga de operadores ++ y
Fichero Tiempo.cpp (2)
/*** operador << ***/
ostream & operator << (ostream &salida, const Tiempo &t){
salida << ((t.hora < 10)? 0: ) << t.hora << :
<< ((t.minutos < 10)? 0: ) << t.minutos << endl;
}
/*** funcion incrementar ***/
void Tiempo::incrementar (){
if (minutos < 59)
++minutos;
else{
minutos=0;
if (hora < 23) ++hora;
else hora=0;
}
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga de operadores ++ y
Fichero Tiempo.cpp (3)
/*** operador ++ (preincremento) ***/
Tiempo & Tiempo::operator ++ (){
incrementar ();
return *this; // devuelve referencia para crear un lvalue
}
/*** operador ++ (posincremento) ***/
Tiempo Tiempo::operator ++ (int ){
Tiempo temporal= *this;
incrementar (); // incrementa el objeto *this
return temporal;// devuelve el objeto sin incremento
}
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases
Sobrecarga de operadores ++ y
Fichero principal.cpp
#include <iostream>
#include Tiempo.h
using namespace std;
int main(){
Tiempo t1 (23,59), t2(23,59);
cout << t1++ << endl << ++t2;
}
23:59
00:00
Gabriel Navarro Tema 3 Abstraccion de datos en C++ : Clases

Vous aimerez peut-être aussi