Sei sulla pagina 1di 18

Práctica 2009

1. [01_01.txt] Proyecto Laboratorio de Programación Bloque I


OBJETIVOS
Construir y manejar clases y objetos.
Gestión de memoria dinámica.
Sobrecarga de operadores.
DESCRIPCIÓN DEL PROBLEMA
Se desea obtener una aplicación que ayude a la gestión de un proyecto de un centro tecnológico, debiendo permitir
modificar los datos básicos de dicho proyecto. La aplicación debe llevar a cabo, además, operaciones básicas (altas,
bajas y modificaciones) de gestión de los investigadores involucrados en dicho proyecto.
ESTRUCTURAS DE DATOS
A continuación, se describen los detalles de las funcionalidades de esta aplicación. Se precisará una clase Fecha
para almacenar datos de este tipo.
Datos de la fecha Tipo de dato
Año Entero
Mes Entero
Dı́a Entero
Para cada investigador, la aplicación gestionará la siguiente información: Datos del investigador Tipo de dato
Nombre Cadena
Apellidos Cadena
Fecha de ingreso en el proyecto Fecha
Categorı́a Enumerado (becario, contratado, fijo)
Salario Real
Para el proyecto de investigación, la aplicación gestionará la siguiente información:
Datos del proyecto Tipo de dato
Nombre Cadena
Presupuesto total Real
Descripción Cadena
Fecha de inicio Fecha
Fecha de finalización Fecha
Investigador principal Puntero a un objeto Investigador
Investigadores Lista dinámica de investigadores
Laboratorio de Programación 1
IMPLEMENTACIÓN
Será necesario crear una clase Investigador, y otra Proyecto. La clase Fecha permitirá gestionar la fecha de
incorporación al proyecto del investigador, ası́ como las fechas de inicio y fin de proyecto.
La clase ListaInvestigadores se encargará de la gestión (búsquedas, altas, bajas, y modificaciones) de investi-
gadores. Nótese que esta lista es dinámica, es decir, no se sabe a priori el número de investigadores que partic-
ipan en él. La lista estará formada por punteros a objetos de la clase Investigador, simplificando de esta forma
la gestión de la misma.
La lista de investigadores (ListaInvestigadores) será dinámica, tal y como se ha expuesto ya. Cada posición
contendrá un puntero a un objeto de la clase Investigador (los investigadores podrán referenciarse según su
posición en la lista).
En caso de que se necesite almacenar un nuevo investigador, será necesario reservar espacio para el nuevo puntero,
crear el objeto y sólo entonces, enlazarlo.
En caso de eliminar una posición, se podrá realizar el comportamiento que se desee: eliminar el objeto, reservar
(menos) espacio, y copiar los punteros al nuevo espacio, o eliminar el puntero de la lista y llevar un control de las

Página 1 de 18
Práctica 2009

posiciones empleadas. En cualquier caso, deberá ser posible saber el número de investigadores en todo momento,
y no deberá haber huecos en dicha lista.
Sobrecarga de operadores Las clases Investigador y Proyecto sobrecargarán el operador >>, de manera que se
pueda obtener por la salida estándar toda la información de un proyecto o de un investigador.
Además, la clase ListaInvestigadores sobrecargará el operador +=, de manera que sea posible añadir un investi-
gador empleando la sintaxis proyecto.lista += investigador.
La misma clase deberá sobrecargar el operador [] para permitir acceder a los investigadores , ası́ como el operador
- postfijo para eliminar al investigador de incorporación más reciente.
Por otra parte, la clase Fecha debe sobrecargar los operadores << y ==, que actuarán sobre la fecha de incorpo-
ración al proyecto, de manera que, por ejemplo, se pueda determinar sobre dos investigadores cuál tiene la fecha
de ingreso más reciente en el proyecto, cuál la más tardı́a, y si son iguales, respectivamente.
Finalmente, la clase ListaPersonas sobrecargará el operador = y el constructor de copia.
A continuación se muestra un ejemplo:
Fecha hoy ( 8 , 1 , 2010 ) ;
Fecha f i n ( 8 , 1 , 2012 ) ;
P r o y e c t o pry ( ” Emigrantes de Ourense ” , hoy , f i n , 10000 ) ;
I n v e s t i g a d o r i n v e s t i g a d o r 1 ( ” B a l t a s a r ” , ” G ar cı́a ” , hoy , I n v e s t i g a d o r : : F i j o , 1 0 0 0 ) ;
pry . i n v e s t i g a d o r e s += i n v e s t i g a d o r 1 ;
c o u t << pry . i n v e s t i g a d o r e s [ 0 ] << e n d l ;
c o u t << pry << e n d l ;
pry . i n v e s t i g a d o r e s −−;
c o u t << pry << e n d l ;

Funcionalidad
La aplicación mostrará inicialmente la información del proyecto (exceptuando los investigadores participantes),
con un menú a continuación que detalle las opciones que se explican más abajo.
En el caso de que sea necesario escoger entre más opciones en un momento dado, estas se mostrarán a modo de
menú igualmente. En todo momento se deberá validar que el usuario selecciona alguna de las opciones disponibles,
mostrando, en caso contrario, un mensaje de error y volviendo a mostrar el menú.
La gestión del proyecto debe permitir realizar las siguientes operaciones:
Modificar datos del proyecto Soportará la edición de los datos básicos del proyecto.
Alta de investigador Permitirá dar de alta un nuevo investigador en el proyecto. Debe pedir los datos del nuevo
investigador, y mostrarlos una vez introducidos. Si el investigador es el investigador principal, se sustituirá al
que ya hubiera en ese momento por este. Si sólo hay un investigador, se hará a este investigador principal
obligatoriamente.
Baja de investigador Solicitará al usuario el número de investigador (su posición en la lista). Si el número no es
válido, mostrará un mensaje indicándolo. En caso contrario, mostrará los datos del investigador en cuestión,
pidiendo confirmación al usuario para su eliminación.
Eliminar al investigador más reciente Buscará al investigador que se ha incorporado más recientemente al
proyecto, y lo eliminará, como si se tratara de una baja. El programa debe listar el grupo de investigadores
resultante para el proyecto.
Listar investigadores Visualizar en pantalla una lista de todos los investigadores (número, apellidos, y nombre).
Modificar datos de investigador Pedirá al usuario el número de un investigador y permitirá modificar cualquiera
de sus datos, a excepción de dicho número. Después de modificar los datos, se mostrará por pantalla toda
la información referente al investigador.

Solución:

// f i c h e r o Usuario . h−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
#i f n d e f USUARIO H
#define USUARIO H
#include <i o s t r e a m >

Página 2 de 18
Práctica 2009

#include <c s t r i n g >


using namespace s t d ;
struct Fecha {
int dia , mes , anno ;
};
enum Busco { amistad , trabajoEnRed , c o m p a r t i r C o n o c i m i e n t o } ;

struct U s u a r i o {
char nombre [ 3 0 ] ;
char u s u a r i o [ 3 0 ] ;
char c o r r e o [ 5 0 ] ;
char password [ 5 0 ] ;
char f o t o [ 5 0 ] ;
Fecha a n i v e r s a r i o ;
char c i u d a d [ 5 0 ] ;
Busco busco ;
};
#endif

// f i c h e r o Usuario . cpp −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−


//#i n c l u d e ” Usuario . h”
void p e d i r D a t o s ( U s u a r i o & u ) ;
void a g r e g a r U s u a r i o ( ) ;
void v i s u a l i z a r U n o ( ) ;
void v i s u a l i z a r T o d o s ( ) ;
void v i s u a l i z a r ( int n , U s u a r i o u ) ;
void e l i m i n a r U s u a r i o ( ) ;
void l i s t a r P o r O r d e n ( ) ;
bool c o r r e o V a l i d o ( char ∗ c o r r e o ) ;
bool f e c h a V a l i d a ( Fecha f ) ;
bool e s B i s i e s t o ( int anno ) ;
bool b u s c o V a l i d o ( int v a l o r ) ;
int p o s U s u a r i o ( char ∗ c o r r e o ) ;
int comparar ( char ∗a , char ∗ b ) ;
const int MAX USUARIOS=100;
int numUsuarios = 0 ;
U s u a r i o u s u a r i o s [MAX USUARIOS ] ;
int main ( ) {
int o p c i o n ;
bool r e p e t i r = true ;
while ( r e p e t i r ) {
c o u t << e n d l
<< ” 0 : S a l i r 1 : A ñadir 2 : Ver t o d o s 3 : Ver uno 4 : E l i m i n a r 5 : L i s t a r ” ;
c o u t << endl<< ” Opcion : ” ;
c i n >> o p c i o n ;
switch ( o p c i o n ) {
case 0 : r e p e t i r=f a l s e ;
break ;
case 1 : a g r e g a r U s u a r i o ( ) ;
break ;
case 2 : v i s u a l i z a r T o d o s ( ) ;
break ;
case 3 : v i s u a l i z a r U n o ( ) ;
break ;
case 4 : e l i m i n a r U s u a r i o ( ) ;
break ;
case 5 : l i s t a r P o r O r d e n ( ) ;

Página 3 de 18
Práctica 2009

break ;
}
}
}
void p e d i r D a t o s ( U s u a r i o & u ) {
c o u t << ”Nombre : ” ;
c i n >> u . nombre ;
c o u t << ” U s u a r i o : ” ;
c i n >> u . u s u a r i o ;
char c o r r e o [ 5 0 ] ;
bool c o r r e c t o = f a l s e ;
while ( ! c o r r e c t o ) {
c o r r e c t o = true ;
c o u t << ” Correo : ” ;
c i n >> c o r r e o ;
i f ( ! correoValido ( correo ) ){
c o u t << ” Correo i n c o r r e c t o ”<<e n d l ;
correcto = false ;
}
i f ( p o s U s u a r i o ( c o r r e o ) != −1){
c o u t << ” Ese c o r r e o ya e x i s t e ”<<e n d l ;
correcto = false ;
}
}
strcpy (u . correo , correo ) ;
c o u t << ” Password : ” ;
c i n >> u . password ;
c o u t << ” Foto : ” ;
c i n >> u . f o t o ;
Fecha f e c h a ;
correcto = false ;
while ( ! c o r r e c t o ) {
c o r r e c t o = true ;
c o u t << ” Dia : ” ;
c i n >> f e c h a . d i a ;
c o u t << ”Mes : ” ;
c i n >> f e c h a . mes ;
c o u t << ”Anno : ” ;
c i n >> f e c h a . anno ;
i f ( ! fechaValida ( fecha ) ){
c o u t << ” Fecha i n c o r r e c t a ” ;
correcto = false ;
}
}
u . aniversario = fecha ;
c o u t << ” Ciudad : ” ;
c i n >> u . c i u d a d ;
correcto = false ;
int busco ;
while ( ! c o r r e c t o ) {
c o r r e c t o = true ;
c o u t << ” I n t e r e s e s ( 1 : amistad , 2 : trabajoEnRed , 3 : c o m p a r t i r C o n o c i m i e n t o ) : ” ;
c i n >> busco ;
i f ( ! b u s c o V a l i d o ( busco ) ) {
c o u t << ” I n t e r e s e s i n c o r r e c t o s ” ;
correcto = false ;
}

Página 4 de 18
Práctica 2009

}
switch ( busco ) {
case amistad :
u . busco = amistad ;
break ;
case trabajoEnRed :
u . busco = trabajoEnRed ;
break ;
case c o m p a r t i r C o n o c i m i e n t o :
u . busco = c o m p a r t i r C o n o c i m i e n t o ;
break ;
}
}
void a g r e g a r U s u a r i o ( ) {
i f ( numUsuarios < MAX USUARIOS) {
Usuario u ;
pedirDatos (u) ;
u s u a r i o s [ numUsuarios++] = u ;
} else {
c o u t << ”No caben mas” ;
}
}
void v i s u a l i z a r U n o ( ) {
int n=0;
cout<< ”Numero : ” ;
c i n >> n ;
i f ( ( n >=0) && ( n < numUsuarios ) ) {
v i s u a l i z a r (n , usuarios [ n ] ) ;
}
}
void v i s u a l i z a r T o d o s ( ) {
f or ( int n = 0 ; n< numUsuarios ; n++){
v i s u a l i z a r (n , usuarios [ n ] ) ;
}
}
void v i s u a l i z a r ( int n , U s u a r i o u ) {
cout
<< e n d l << ”Num: ” << n
<< ” Nombre : ”<< u . nombre << e n d l
<< ” U s u a r i o : ”<< u . u s u a r i o << e n d l
<< ” Correo : ”<< u . c o r r e o << e n d l
<< ” Password : ”<< u . password << e n d l
<< ” Foto : ”<< u . f o t o << e n d l
<< ” A n i v e r s a r i o : ”<< u . a n i v e r s a r i o . d i a << ”/”
<< u . a n i v e r s a r i o . mes << ”/”
<< u . a n i v e r s a r i o . anno << e n d l
<< ” Ciudad : ”<< u . c i u d a d << e n d l
<< ” I n t e r e s e s : ”<< u . busco << e n d l
;
}
void e l i m i n a r U s u a r i o ( ) {
int u=0;
cout<< ”Numero : ” ;
c i n >> u ;
i f ( u < numUsuarios ) {
f or ( int n = u ; n< numUsuarios −1; n++){
usuarios [ n ] = usuarios [ n+1];

Página 5 de 18
Práctica 2009

}
numUsuarios −−;
} else {
c o u t << ”No hay t a n t o s u s u a r i o s ”<<e n d l ;
}
}
void l i s t a r P o r O r d e n ( ) {
U s u a r i o ∗ or d e n ad os [MAX USUARIOS ] ;
f or ( int n=0; n< numUsuarios ; n++){
or d e n ad os [ n ] = &( u s u a r i o s [ n ] ) ;
}
bool estanOrdenados = f a l s e ;
while ( ! estanOrdenados ) {
estanOrdenados = true ;
f or ( int n=0; n< numUsuarios −1;n++){
i f ( comparar ( or d e n ad os [ n]−> c o r r e o , or d e n ad os [ n+1]−> c o r r e o ) >0){
U s u a r i o ∗ tmp = or d e n ad os [ n ] ;
or d e n ad os [ n ] = or d e n ad os [ n + 1 ] ;
or d e n ad os [ n+1] = tmp ;
estanOrdenados = f a l s e ;
}
}
}
f or ( int n=0; n< numUsuarios ; n++){
v i s u a l i z a r ( n , ∗ or d e n ad os [ n ] ) ;
}
}
bool c o r r e o V a l i d o ( char ∗ c o r r e o ) {
char ∗ p = c o r r e o ;
bool t i e n e A r r o b a = f a l s e ;
while ( ∗ p ) {
i f ( ∗ p == ’@ ’ ) t i e n e A r r o b a = true ;
p++;
}
return t i e n e A r r o b a ;
}
bool f e c h a V a l i d a ( Fecha f e c h a ) {
bool c o r r e c t o = true ;
i f ( f e c h a . anno < 0 ) {
c o u t << e n d l << ” El anno no e s c o r r e c t o . ” ;
correcto = false ;
} e l s e i f ( ( f e c h a . mes < 0 ) | | ( f e c h a . mes > 1 2 ) ) {
c o u t << e n d l << ” El mes no e s c o r r e c t o . ” ;
correcto = false ;
} else i f ( fecha . dia < 0) {
c o u t << e n d l << ” El d i a no e s c o r r e c t o . ” ;
correcto = false ;
} else {
switch ( f e c h a . mes ) {
case 1 :
case 3 :
case 5 :
case 7 :
case 8 :
case 1 0 :
case 1 2 :
i f ( fecha . dia > 31) {

Página 6 de 18
Práctica 2009

c o u t << e n d l << ” El d i a no e s c o r r e c t o . ” ;
correcto = false ;
}
break ;
case 2 :
i f ( fecha . dia > 29) {
c o u t << e n d l << ” El d i a no e s c o r r e c t o . ” ;
correcto = false ;
} e l s e i f ( ( f e c h a . d i a == 2 9 ) &&(! e s B i s i e s t o ( f e c h a . anno ) ) ) {
c o u t << e n d l << ” El d i a no e s c o r r e c t o . ” ;
correcto = false ;
}
break ;
default :
i f ( f e c h a . d i a >30){
c o u t << e n d l << ” El d i a no e s c o r r e c t o . ” ;
correcto = false ;
}
}
}
return c o r r e c t o ;
}

bool e s B i s i e s t o ( int anno ) {


bool b i s i e s t o = f a l s e ;
i f ( ( anno % 4 ) == 0 ) {
i f ( ( anno % 1 0 0 ) == 0 ) {
i f ( ( anno % 4 0 0 ) == 0 ) {
b i s i e s t o = true ;
}
} else {
b i s i e s t o = true ;
}
}
return b i s i e s t o ;
}

bool b u s c o V a l i d o ( int v a l o r ) {
return ( v a l o r==amistad | | v a l o r==trabajoEnRed | | v a l o r==c o m p a r t i r C o n o c i m i e n t o ) ;
}
int p o s U s u a r i o ( char ∗ c o r r e o ) {
Usuario ∗ usuario = u s u a r i o s ;
int pos = −1;
f or ( int pos = 0 ; pos < numUsuarios ; pos ++, u s u a r i o++){
i f ( comparar ( u s u a r i o −>c o r r e o , c o r r e o )==0){
return pos ;
}
}
return pos ;
}
int comparar ( char ∗ cs , char ∗ c t ) {
int r e s ;
while ( 1 ) {
i f ( ( r e s = ∗ c s − ∗ c t++) != 0 | | ! ∗ c s++)
break ;
}
return r e s ;

Página 7 de 18
Práctica 2009

2. [01_02.txt] Continuando con el desarrollo de un software para la gestión de una red social, vamos a suponer
ahora que queremos implementar la parte de gestion de grupos. En la red social se van a poder crear grupos,
donde cada grupo va a estar formado por un numero variable de usuarios. La informacion que es necesario
almacenar de cada grupo es:

Nombre
Imagen
Descripción
Pagina Web
Numero de miembros
Informacion de sus miembros

De cada uno de los miembros del grupo es necesario almacenar la siguiente informacin:

Nombre y apellidos
Nombre de usuario
Correo electronico
Fecha de alta en el grupo

Definir las clases necesarias para que utilizando memoria dinamica sea correcto el siguiente trozo de codigo.
// Usuario e s e l nombre de l a c l a s e
Grupo g1 ( ”AVIA” , 3 ) ;
Grupo g2 ( ”LIMIA” ) ;

c o u t << ”\nVamos a l e e r l o s d a t o s ( i n c l u i d o s l o s miembros ) de l o s dos gr u p os . \ n” ;


c o u t << ”\ nPara e l p r i m e r grupo . \ n” ;
c i n >> g1 ;
c o u t << ”\ nPara e l segundo u s u a r i o . \ n” ;
c i n >> g2 ;

c o u t << ”\nComparamos l o s miembros de l o s dos gr u p os . \ n” ;


i f ( g1 < g2 )
cout
<< ”\ t E l grupo ” << g1 . obtenerNombre ( )
<< ” t i e n e menos miembros que e l grupo ”
<< g2 . obtenerNombre ( ) << e n d l ;
else
cout
<< ”\ t E l grupo ” << g2 . obtenerNombre ( )
<< ” t i e n e menos miembros que e l grupo ”
<< g1 . obtenerNombre ( ) << e n d l ;
c o u t << ”\ nSe va a e l i m i n a r e l miembro mas a n t i g u o d e l grupo ” << g1 .
obtenerNombre ( ) << e n d l ;
g1−−;
c o u t << ”\ nLos d a t o s d e l grupo son ” << g1 . obtenerNombre ( ) << ” son : \ n”<<g1 ;
c o u t << ”\ nCuantos miembros d e s e a s a g r e g a r a l grupo ” << g2 . obtenerNombre ( ) << ”
?\n” ;
c i n >> num ;
g2 = num + g2 ;

Ademas, se nos pide el almacenamiento de los datos de los usuarios de un grupo en un fichero, asi como la opcion
de poder actualizar dicho fichero. Para ello, debemos implementar dos funciones mas:

Página 8 de 18
Práctica 2009

1. Una que almacene en un fichero, cuyo nombre se introduce por teclado, los datos de los usuarios de un
grupo.
2. Otra que actualice el nombre de usuario de los usuarios almacenados en el fichero creado por la funcion ante-
rior, de forma que, para un determinado usuario de un grupo, se cambie su nombre de usuario directamente
sobre el archivo.

Solución:

// f i c h e r o Grupos . h−−−−−−−−−−−−−−−−−−−−−−−−−−−−
#i f n d e f GRUPO H
#define GRUPO H
#include <i o s t r e a m >
#include <f s t r e a m >
#include <c s t r i n g >
using namespace s t d ;
struct Fecha {
int dia , mes , anno ;
bool operator >(Fecha &f ) ;
};
c l a s s Miembro{
public :
char nombre [ 5 0 ] ;
char u s u a r i o [ 5 0 ] ;
char c o r r e o [ 5 0 ] ;
Fecha f e c h a A l t a ;
};
c l a s s Grupo{
public :
Grupo ( const char ∗ nombre , int numMiembros=1) ;
Grupo ( const Grupo &) ;
˜Grupo ( ) ;
char ∗ obtenerNombre ( ) ;
Grupo operator−−(int ) ;
bool operator <(const Grupo &) ;
Grupo & operator=(const Grupo &) ;
char nombre [ 5 0 ] ;
char imagen [ 5 0 ] ;
char d e s c r i p c i o n [ 5 0 ] ;
char paginaWeb [ 5 0 ] ;
int numMiembros ;
Miembro ∗ miembros ;
};
Grupo operator+( int n , const Grupo & g ) ;
void e s c r i b e G r u p o ( const Grupo &g , char ∗ nombreFichero ) ;
void a c t u a l i z a G r u p o ( char ∗ nombreFichero ) ;
ostream & operator << ( ostream & o , const Grupo & g ) ;
i s t r e a m & operator >> ( i s t r e a m & i , Grupo & g ) ;
ostream & operator << ( ostream & o , const Miembro & m) ;
ostream & operator << ( ostream & o , const Fecha & f ) ;
i s t r e a m & operator >> ( i s t r e a m & i , Fecha& f ) ;
i s t r e a m & operator >> ( i s t r e a m & i , Miembro & m) ;
i s t r e a m & operator >> ( i s t r e a m & i , Grupo & g ) ;
#endif
// f i c h e r o Grupos . cpp −−−−−−−−−−−−−−−−−−−−−−−−−
//#i n c l u d e ” Grupos . h”
bool Fecha : : operator >(Fecha & f ) {
i f ( f . anno > anno ) return true ;

Página 9 de 18
Práctica 2009

i f ( f . mes > mes ) return true ;


i f ( f . d i a > d i a ) return true ;
return f a l s e ;
}
Grupo : : Grupo ( const char ∗ nombre , int numMiembros )
: numMiembros ( numMiembros ) {
s t r c p y ( this−>nombre , nombre ) ;
miembros = new Miembro [ numMiembros ] ;
}
Grupo : : Grupo ( const Grupo &g )
: numMiembros ( g . numMiembros ) {
s t r c p y ( this−>nombre , g . nombre ) ;
miembros = new Miembro [ numMiembros ] ;
f or ( int n=0; n<numMiembros ; n++){
miembros [ n ] = g . miembros [ n ] ;
}
}
Grupo : : ˜ Grupo ( ) {
delete [ ] miembros ;
}
char ∗ Grupo : : obtenerNombre ( ) {
return nombre ;
}
Grupo Grupo : : operator−−(int ) {
i f ( numMiembros ==0 ) return ∗ t h i s ;
Grupo r e t ( ∗ t h i s ) ;
int posMasAntiguo= 0 ;
f or ( int n=0; n<numMiembros ; n++){
i f ( miembros [ n ] . f e c h a A l t a > miembros [ posMasAntiguo ] . f e c h a A l t a ) {
posMasAntiguo = n ;
}
}
f or ( int n = posMasAntiguo ; n< numMiembros −1; n++){
miembros [ n ] = miembros [ n + 1 ] ;
}
numMiembros−−;
return r e t ;
}
bool Grupo : : operator <(const Grupo &g ) {
return ( numMiembros < g . numMiembros ) ;
}
Grupo & Grupo : : operator=(const Grupo &g ) {
i f (&g == t h i s ) {
return ∗ t h i s ;
}
delete [ ] miembros ;
s t r c p y ( this−>nombre , g . nombre ) ;
miembros = new Miembro [ numMiembros ] ;
f or ( int n=0; n<numMiembros ; n++){
miembros [ n ] = g . miembros [ n ] ;
}
return ∗ t h i s ;
}
Grupo operator+( int n , const Grupo & g ) {
Grupo r e t ( g . nombre , g . numMiembros+n ) ;
f or ( int n=0; n<g . numMiembros ; n++){
r e t . miembros [ n ] = g . miembros [ n ] ;

Página 10 de 18
Práctica 2009

}
return r e t ;
}
void e s c r i b e G r u p o ( const Grupo &g , char ∗ nombreFichero ) {
o f s t r e a m f ( nombreFichero , i o s : : out | i o s : : b i n a r y ) ;
if (! f ) {
c o u t << ” E r r o r de e s c r i t u r a ” ;
return ;
}
f or ( int n=0; n<g . numMiembros ; n++){
f . w r i t e ( ( char ∗ ) &g . miembros [ n ] , s i z e o f ( Miembro ) ) ;
}
}
void a c t u a l i z a G r u p o ( char ∗ nombreFichero ) {
char oldName [ 5 0 ] , newName [ 5 0 ] ;
Miembro miembro ;
f s t r e a m f ( nombreFichero , i o s : : i n | i o s : : out | i o s : : b i n a r y ) ;
c o u t << ”Nombre a cambiar : ” ;
c i n >> oldName ;
c o u t << ”Nombre nuevo ” ;
c i n >> newName ;
while ( f . r e a d ( ( char ∗ ) &miembro , s i z e o f ( Miembro ) ) ) {
i f ( ! strcmp ( miembro . u s u a r i o , oldName ) ) {
s t r c p y ( miembro . u s u a r i o , newName ) ;
f . s e e k p ( s i z e o f ( Miembro ) ∗ −1) ;
f . w r i t e ( ( char ∗ )&miembro , s i z e o f ( Miembro ) ) ;
break ;
}
}
}
ostream & operator << ( ostream & o , const Grupo & g ) {
o
<< ”Nombre : ” << g . nombre << e n d l
<< ” Imagen : ” << g . imagen << e n d l
<< ” D e s c r i p c i o n : ”<< g . d e s c r i p c i o n << e n d l
<< ” Pagina web : ” << g . paginaWeb << e n d l
<< ”Numero de miembros : ” << g . numMiembros<< e n d l
<< ” Miembros : ” << e n d l
;
f or ( int n=0; n<g . numMiembros ; n++){
o << g . miembros [ n ] ;
}
return o ;
}
i s t r e a m & operator >> ( i s t r e a m & i , Fecha& f ) {
c o u t << ” Dia , mes , anno : ” ;
return i >> f . d i a >> f . mes >> f . anno ;
}
i s t r e a m & operator >> ( i s t r e a m & i , Miembro & m) {
c o u t << ”Nombre : ” ; i >> m. nombre ;
c o u t << ” U s u a r i o : ” ; i >> m. u s u a r i o ;
c o u t << ” Correo : ” ; i >> m. c o r r e o ;
c o u t << ” Fecha de a l t a : ” ; i >>m. f e c h a A l t a ;
return i ;
}
i s t r e a m & operator >> ( i s t r e a m & i , Grupo & g ) {
c o u t << ”Nombre : ” ; i >> g . nombre ;

Página 11 de 18
Práctica 2009

c o u t << ” Imagen : ” ; i >> g . imagen ;


c o u t << ” D e s c r i p c i o n : ” ; i . i g n o r e ( ) ; i . g e t l i n e ( g . d e s c r i p c i o n , 5 0 ) ;
c o u t << ” Pagina web : ” ; i >>g . paginaWeb ;
f or ( int n=0; n<g . numMiembros ; n++){
i >> g . miembros [ n ] ;
}
return i ;
}
ostream & operator << ( ostream & o , const Miembro & m) {
return o
<< ”Nombre : ” << m. nombre << e n d l
<< ” U s u a r i o : ” << m. u s u a r i o << e n d l
<< ” Correo : ”<< m. c o r r e o << e n d l
<< ” Fecha de a l t a : ” << m. f e c h a A l t a << e n d l
;
}
ostream & operator << ( ostream & o , const Fecha & f ) {
return o
<< f . d i a << ” /” << f . mes << ”/ ”<< f . anno ;
}
int main ( ) {
Grupo g1 ( ”AVIA” , 3 ) ;
Grupo g2 ( ”LIMIA” ) ;

c o u t << ”\nVamos a l e e r l o s d a t o s ( i n c l u i d o s l o s miembros ) de l o s dos gr u p os


. \ n” ;
c o u t << ”\ nPara e l p r i m e r grupo . \ n” ;
c i n >> g1 ;
c o u t << ”\ nPara e l segundo u s u a r i o . \ n” ;
c i n >> g2 ;

c o u t << ”\nComparamos l o s miembros de l o s dos gr u p os . \ n” ;


i f ( g1 < g2 )
cout
<< ” \ t E l grupo ” << g1 . obtenerNombre ( )
<< ” t i e n e menos miembros que e l grupo ”
<< g2 . obtenerNombre ( ) << e n d l ;
else
cout
<< ” \ t E l grupo ” << g2 . obtenerNombre ( )
<< ” t i e n e menos miembros que e l grupo ”
<< g1 . obtenerNombre ( ) << e n d l ;
c o u t << ”\ nSe va a e l i m i n a r e l miembro mas a n t i g u o d e l grupo ” << g1 .
obtenerNombre ( ) << e n d l ;
g1−−;
c o u t << ”\ nLos d a t o s d e l grupo son ” << g1 . obtenerNombre ( ) << ” son : \ n”<<g1 ;
c o u t << ”\ nCuantos miembros d e s e a s a g r e g a r a l grupo ” << g2 . obtenerNombre ( )
<< ” ?\n” ;
int num ;
c i n >> num ;
g2 = num + g2 ;
}

3. [01_03.txt] Partiendo del programa desarrollado en el ejercicio anterior (Bloque II), se realizaran varias mod-
ificaciones relacionadas con herencia, composicion, polimorfismo, y gestion de excepciones.
El ejercicio anterior suponı́a la creación de una clase Grupo, formada por un numero variable de usuarios, y que

Página 12 de 18
Práctica 2009

se implementó como un array dinámico de objetos de la clase Usuario. El primer cambio va a consistir en que
la parte dinámica del grupo va a estar formada por fotos y vı́deos. La idea es que en una red social cualquiera
de los miembros de un grupo podrı́a publicar y compartir archivos de fotos y vı́deos. La clase Archivo podrı́a ser
similar a esta:
c l a s s Archivo {
public :
const s t r i n g &g e t T i t u l o ( ) ;
const s t r i n g &getRuta ( ) ;
v i r t u a l const s t r i n g &t o S t r i n g ( ) = 0 ;
Archivo ( const s t r i n g &r , const s t r i n g &t ) ;
private :
s t r i n g ruta ;
string titulo ;
};

Las transformaciones a realizar serán las siguientes:

Definir las clases Foto y Video como especializaciones de la clase Archivo. La clase Foto tendrá una variable
miembro adicional album, y la clase Video una variable codigoInsertar (código HTML para incrustar el
vı́deo en una Web). El contenido de esta variable se generará por una función que reciba el ancho y alto
seleccionado. También habrá una función que devuelva dicho código HTML.
El vector de archivos de cada grupo se alojará en memoria dinámica, encargándose la propia clase Grupo de
su gestión. Este vector dinámico debe ser creado utilizando un vector de la STL. Como se quiere aprovechar
la flexibilidad de la ligadura dinámica, el tipo base del contenedor será un puntero a la clase Archivo, que
permitirá que el vector contenga indistintamente vı́deos o fotos.
El método virtual toString()es similar al operador , devolviendo el contenido del objeto, que será diferente
para las clases Foto y Video.
Todos los errores que en el ejercicio anterior se mostraban por consola y hacı́an que el programa se detuviera,
deben ser gestionados mediante excepciones. Ası́, los errores del operador – (no hay archivos que eliminar)
deben ser tratados ahora mediante el lanzamiento de excepciones.
El main (sin incluir tratamiento de excepciones) podı́a ser algo ası́:
unsigned int num ;
char cad [ 3 ] ;

Grupo g1 ( ”AVIA” ) ;
Grupo g2 ( ”LIMIA” ) ;

c o u t << ” \nVamos a l e e r l o s d a t o s ( i n c l u i d o s l o s a r c h i v o s ) de l o s dos gr u p os


. \ n” ;
c o u t << ” \ nPara e l p r i m e r grupo . \ n” ;
c i n >> g1 ;
c o u t << ” \ nPara e l segundo grupo . \ n” ;
c i n >> g2 ;

c o u t << ” \nComparamos e l numero de a r c h i v o s de l o s dos gr u p os . \ n” ;


i f ( g1 < g2 )
c o u t << ”\ t E l grupo ” << g1 . obtenerNombre ( )
<< ” t i e n e menos a r c h i v o s que e l grupo ”
<< g2 . obtenerNombre ( ) << e n d l ;
e l s e c o u t << ”\ t E l grupo ” << g2 . obtenerNombre ( )
<< ” t i e n e menos a r c h i v o s que e l grupo ”
<< g1 . obtenerNombre ( ) << e n d l ;

c o u t << endl<< ” Se va a e l i m i n a r e l ú l t i m o a r c h i v o d e l grupo ”


<< g1 . obtenerNombre ( ) << e n d l ;
−−g1 ;
c o u t << ” \ nDespues de q u i t a r l e e l u l t i m o a r c h i v o l o s d a t o s d e l grupo ”

Página 13 de 18
Práctica 2009

<< g1 . obtenerNombre ( ) << ” son : \ n” ;


c o u t << g1 ;

c o u t << ” \ nCuantos a r c h i v o s d e s e a s a g r e g a r a l grupo ”


<< g2 . obtenerNombre ( ) << ” ?\n” ;
c i n . g e t l i n e ( cad , 3 ) ;
num = a t o i ( cad ) ;
g2 = num + g2 ;
c o u t << ” \ nDespues de a g r e g a r l e a r c h i v o s a l grupo ”
<< g2 . obtenerNombre ( ) << ” s u s d a t o s son : \ n” ;
c o u t << g2 ;

Solución:

// f o t o s Y V i d e o s . h−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
#i f n d e f FOTOSYVIDEOS H
#define FOTOSYVIDEOS H
#include <v e c t o r >
#include <s t r i n g >
#include <i o s t r e a m >
#include <c s t r i n g >
#include <c s t d l i b >

using namespace s t d ;
const int TAM MAXIMO=100;

c l a s s Archivo ;

c l a s s Grupo {
private :
char nombre [TAM MAXIMO ] ;
char imagen [TAM MAXIMO ] ;
char d e s c r i p c i o n [TAM MAXIMO ] ;
char web [TAM MAXIMO ] ;
v e c t o r <Archivo ∗> almac e n A r c h iv os ;
public :
Grupo ( const char ∗ s ) ;
s t r i n g obtenerNombre ( ) ;
friend i s t r e a m & operator >>(i s t r e a m &i , Grupo & g ) ;
friend ostream & operator <<(ostream &i , Grupo & g ) ;
friend bool operator <(Grupo &a , Grupo& b ) ;
Grupo& operator −−() ;
friend Grupo& operator+( int n , Grupo & g ) ;
};

c l a s s Archivo {
public :
v i r t u a l ˜ Archivo ( ) ;
Archivo ( const s t r i n g &r , const s t r i n g &t ) ;
const s t r i n g &g e t T i t u l o ( ) {
return t i t u l o ;
}
const s t r i n g &getRuta ( ) {
return r u t a ;
}
v i r t u a l const s t r i n g t o S t r i n g ( ) = 0 ;
private :

Página 14 de 18
Práctica 2009

s t r i n g ruta ;
string titulo ;
};

c l a s s Foto : public Archivo {


public :
v i r t u a l ˜ Foto ( ) ;
Foto ( s t r i n g u r l , s t r i n g t i t u l o , s t r i n g album ) ;
const s t r i n g t o S t r i n g ( ) ;
s t r i n g getAlbum ( ) {
return album ;
}
friend i s t r e a m & operator >>(i s t r e a m &i , Grupo & g ) ;
private :
s t r i n g album ;
};

c l a s s Video : public Archivo {


public :
v i r t u a l ˜ Video ( ) ;
const s t r i n g t o S t r i n g ( ) ;
Video ( s t r i n g u r l , s t r i n g t i t u l o , s t r i n g c o d i g o I n s e r t a r ) ;
string getCodigoInsertar () {
return c o d i g o I n s e r t a r ;
}
friend i s t r e a m & operator >>(i s t r e a m &i , Grupo & g ) ;
private :
string codigoInsertar ;
};

i s t r e a m & operator >>(i s t r e a m &i , Grupo & g ) ;


s t r i n g codigoHTML ( int ancho , int a l t o ) ;
ostream & operator << ( ostream &o , const Grupo &g ) ;
#endif // FOTOSYVIDEOS H

// f o t o s Y V i d e o s . cpp −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
//#i n c l u d e ” f o t o s Y v i d e o s . h”

Archivo : : Archivo ( const s t r i n g &ruta , const s t r i n g &t i t u l o )


: ruta ( ruta ) , t i t u l o ( t i t u l o ) {
}
Archivo : : ˜ Archivo ( ) {

}
Foto : : Foto ( s t r i n g u r l , s t r i n g t i t u l o , s t r i n g album )
: Archivo ( u r l , t i t u l o ) , album ( album ) {
}
Foto : : ˜ Foto ( ) {

}
s t r i n g Grupo : : obtenerNombre ( ) {
return nombre ;
}

const s t r i n g Foto : : t o S t r i n g ( ) {
string ret ;
r e t+= g e t T i t u l o ( ) ;

Página 15 de 18
Práctica 2009

r e t+=” , ” ;
r e t+= getRuta ( ) ;
r e t+=” , ” ;
r e t+= getAlbum ( ) ;
return r e t ;
}

Video : : ˜ Video ( ) {

Video : : Video ( s t r i n g u r l , s t r i n g t i t u l o , s t r i n g c o d i g o I n s e r t a r )
: Archivo ( u r l , t i t u l o ) , c o d i g o I n s e r t a r ( c o d i g o I n s e r t a r ) {

};

const s t r i n g Video : : t o S t r i n g ( ) {
string ret ;
r e t+= g e t T i t u l o ( ) ;
r e t+=” , ” ;
r e t+= getRuta ( ) ;
r e t+=” , ” ;
r e t+= g e t C o d i g o I n s e r t a r ( ) ;
return r e t ;
}

Grupo : : Grupo ( const char ∗ s ) {


s t r c p y ( nombre , s ) ;
}

i s t r e a m & operator >>(i s t r e a m &i , Grupo & g ) {


cout<<” I n t r o d u c e e l nombre d e l grupo : ” ;
i . g e t l i n e ( g . nombre ,TAM MAXIMO) ;
cout<<” I n t r o d u c e l a imagen d e l grupo : ” ;
i . g e t l i n e ( g . imagen ,TAM MAXIMO) ;
cout<<” I n t r o d u c e l a d e s c r i p c i o n d e l grupo : ” ;
i . g e t l i n e ( g . d e s c r i p c i o n ,TAM MAXIMO) ;
cout<<” I n t r o d u c e l a web d e l grupo : ”<<e n d l ;
i . g e t l i n e ( g . web ,TAM MAXIMO) ;
cout<<”Ahora i n t r o d u c i r e m o s l o s d i s t i n t o s a r c h i v o s . ”<<e n d l ;
Archivo ∗ tmp=0;
char c ;
s t r i n g u r l , t i t u l o , album , c o d i g o I n s e r t a r ;
int ancho , a l t o ;
do {
cout<<”F : f o t o , V: video , S : f i n ”<<e n d l ;
c i n >>c ;
i f ( c==’F ’ or c==’V ’ or c==’ S ’ ) {
switch ( c ) {
case ’F ’ :
cout<<” I n t r o d u c e l a u r l de l a f o t o : ” ;
i . ignore () ;
getline ( i , url ) ;
cout<<” I n t r o d u c e e l t i t u l o de l a f o t o : ” ;
getline ( i , titulo ) ;
cout<<” I n t r o d u c e e l album de l a f o t o : ” ;
g e t l i n e ( i , album ) ;

Página 16 de 18
Práctica 2009

tmp=new Foto ( u r l , t i t u l o , album ) ;


g . almac e n A r c h iv os . push back ( tmp ) ;
break ;
case ’V ’ :
cout<<” I n t r o d u c e l a u r l d e l v i d e o : ” ;
i . ignore () ;
getline ( i , url ) ;
cout<<” I n t r o d u c e e l t i t u l o d e l v i d e o : ” ;
getline ( i , titulo ) ;
cout<<” I n t r o d u c e e l ancho d e l v i d e o : ” ;
c i n >>ancho ;
cout<<” I n t r o d u c e e l a l t o d e l v i d e o : ” ;
c i n >>a l t o ;
c o d i g o I n s e r t a r=codigoHTML ( ancho , a l t o ) ;
tmp=new Video ( u r l , t i t u l o , c o d i g o I n s e r t a r ) ;
g . almac e n A r c h iv os . push back ( tmp ) ;
break ;
}
} else {
cout<<” El s i m b o l o i n t r o d u c i o d o e s i n c o r r e c t o : ”<<e n d l ;
}
} while ( c != ’ S ’ ) ;
return i ;
}

s t r i n g codigoHTML ( int ancho , int a l t o ) {


s t r i n g cadena=” Esto e s e l c o d i g o HTML d e l v i d e o . ” ;
return cadena ;
}
bool operator <(Grupo &a , Grupo& b ) {
return a . almac e n A r c h iv os . s i z e ( ) < b . almac e n A r c h iv os . s i z e ( ) ;
}
Grupo& Grupo : : operator −−() {
almac e n A r c h iv os . pop back ( ) ;
return ∗ t h i s ;
}
Grupo& operator+( int n , Grupo & g ) {
return g ;
}
ostream & operator << ( ostream &o , Grupo &g ) {
o
<<”Nombre : ”<<g . nombre<<e n d l
<<” Imagen : ”<<g . imagen<<e n d l
<<” D e s c r i p c i o n : ”<<g . d e s c r i p c i o n <<e n d l
<<”Web : ”<<g . web<<e n d l
<<” A r c h i v o s d e l grupo : ”<<e n d l ;
// F a l t a mostrar l o s a r c h i v o s con e l i t e r a t o r
v e c t o r <Archivo ∗ >:: i t e r a t o r i ;
i = g . almac e n A r c h iv os . b e g i n ( ) ;
while ( i != g . almac e n A r c h iv os . end ( ) ) {
c o u t << ( ∗ i )−>t o S t r i n g ( )<<e n d l ;
i ++;
}

return o ;

Página 17 de 18
Práctica 2009

// main . cpp −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−


#include <i o s t r e a m >
//#i n c l u d e ” f o t o s Y v i d e o s . h”
using namespace s t d ;

int main ( ) {
unsigned int num ;
char cad [ 3 ] ;

Grupo g1 ( ”AVIA” ) ;
Grupo g2 ( ”LIMIA” ) ;

c o u t << ”\nVamos a l e e r l o s d a t o s ( i n c l u i d o s l o s a r c h i v o s ) de l o s dos


gr u p os . \ n” ;
c o u t << ”\ nPara e l p r i m e r grupo . \ n” ;
c i n >> g1 ;
c o u t << ”\ nPara e l segundo grupo . \ n” ;
c i n >> g2 ;

c o u t << ”\nComparamos e l numero de a r c h i v o s de l o s dos gr u p os . \ n” ;


i f ( g1 < g2 )
c o u t << ”\ t E l grupo ” << g1 . obtenerNombre ( )
<< ” t i e n e menos a r c h i v o s que e l grupo ”
<< g2 . obtenerNombre ( ) << e n d l ;
e l s e c o u t << ”\ t E l grupo ” << g2 . obtenerNombre ( )
<< ” t i e n e menos a r c h i v o s que e l grupo ”
<< g1 . obtenerNombre ( ) << e n d l ;

c o u t << ”\ nSe va a e l i m i n a r e l u l t i m o a r c h i v o d e l grupo ”


<< g1 . obtenerNombre ( ) << e n d l ;
−−g1 ;
c o u t << ”\ nDespues de q u i t a r l e e l u l t i m o a r c h i v o l o s d a t o s d e l grupo ”
<< g1 . obtenerNombre ( ) << ” son : \ n” ;
c o u t << g1 ;

c o u t << ”\ nCuantos a r c h i v o s d e s e a s a g r e g a r a l grupo ”


<< g2 . obtenerNombre ( ) << ” ?\n” ;
c i n . g e t l i n e ( cad , 3 ) ;
num = a t o i ( cad ) ;
g2 = num + g2 ;
c o u t << ”\ nDespues de a g r e g a r l e a r c h i v o s a l grupo ”
<< g2 . obtenerNombre ( ) << ” s u s d a t o s son : \ n” ;
c o u t << g2 ;
}

Página 18 de 18

Potrebbero piacerti anche