Bloque práctico 1: C++

Anuncio
Metodología de la Programación II
Bloque práctico 1: C++
1: Programación modular, herencia simple y
polimorfismo.
En esta práctica utilizaremos las capacidades de programación orientada a
objetos, tanto básicas como avanzadas, de que dispone C++. El objetivo de la práctica
es programar un lienzo y figuras que se puedan pintar utilizando herencia y
polimorfismo.
1) Programar un lienzo y figuras dibujables
Un Lienzo es una matriz de puntos de imagen (píxels) de dos dimensiones al que se le
pueden poner los píxels de un color determinado (un entero). Un lienzo se puede
rellenar de un color, con lo que todos los píxels del lienzo tendrían dicho valor. Un
lienzo, finalmente, se puede mostrar por pantalla, traduciendo según el tipo de Lienzo el
entero a una representación.
Se debe implementar, asimismo, una clase heredada de Lienzo (LienzoCaracter) , cuya
representación sea el entero interpretado como un carácter ASCII.
Para pintar en este Lienzo, vamos a construir unas figuras que sepan como
pintarse en un lienzo, teniendo en cuenta que si el dibujo se sale de los límites del
mismo no se pinten los píxeles que se salen del lienzo (es decir, si la figura se sale del
lienzo, no da error, sólo visualiza la parte que cae dentro del mismo).
Una figura contiene una posición de origen expresada por dos enteros que
determinan la posición del eje x y el eje y. Esta posición es una clase aparte contenida
por la figura.
Una figura debe tener un método que devuelva una cadena de caracteres ( char *
de C, no string de C++) con la descripción del tipo de figura y su contenido.
Una figura tiene un color determinado por un entero.
Las figuras disponibles son:
Punto: Posición y color.
Circulo: Centro (una posición) , radio (entero) y color.
Linea : Posición inicial, posición final y color.
Bitmap : Posición inicial (esquina superior izquierda), ancho, alto ,contenido y
color.
Metodología de la Programación II
Notas sobre los métodos de Dibujo de cada figura:
Circulo y Linea deberán calcular la posición de los píxels en el lienzo usando
funciones trigonométricas y el número PI (disponible en la biblioteca math.h).
Ejemplo: dibujar un Circulo de radio 3 y color '#'
#####
##
##
#
#
#
#
#
#
##
##
#####
Ejemplo: dibujar una Linea que vaya de la posición(0,0) a la posición(5,5) en
color '.'
.
.
.
.
.
.
.
.
Bitmap se construye como una cadena que contiene unos ("1") en las posiciones
que se quiere pintar y "0" en las no pintables (bitmap monocromo).
Un ejemplo de bitmap de alto 3 y ancho tres es el siguiente:
Contenido del bitmap: "001001001"
Bitmap dibujado con el color '*':
"
*
*
*"
donde " " serian pixels no dibujados y * el píxel dibujado en el color *
Estas figuras deben contener en una superclase todas aquellas características que
les sean comunes.
Finalmente, debe quedar compilada como una biblioteca estática, llamada
LibFiguras, que se pueda enlazar a otros programas.
Por comodidad y para los ejemplos programados que siguen, cree un archivo de
cabecera Libfiguras.hpp, que incluya todas las cabeceras creadas para los
módulos de esta biblioteca.
Metodología de la Programación II
Compile y enlace el código siguiente en un proyecto diferente que utilice la
librería creada. Compruebe que su librería obtiene la salida deseada. En caso contrario,
modifique su librería para que funcione correctamente.
PruebaLib.Cpp
int main(int argc, char *argv[])
{ LienzoCaracter z(15,12);
Posicion pos1(1,1),pos2(5,5),pos3(8,8);
Punto p(pos1,'*'),p1(pos2,'+');
Circulo c(pos2,4,'^');
Linea l(pos1,pos3,'.');
char* contenido =strdup("001001001");
Bitmap b(Posicion(2,2),contenido,3,3,'@');
z.rellenar(' '); // Pinta dos puntos, un bitmap
p.pintar(&z);
// y un circulo de radio 4
p1.pintar(&z);
b.pintar(&z);
c.pintar(&z);
z.mostrar();
cout << p.descripcion()<< "\n";
cout << b.descripcion()<< "\n";
system("PAUSE"); //Limpia el lienzo
z.rellenar();
//Dibuja un circulo y una linea
c.setRadio(5); //cambio radio
c.setPos(pos3);//cambio posicion
c.pintar(&z);
l.pintar(&z);
z.mostrar();
cout << c.descripcion()<< "\n";
cout << l.descripcion()<< "\n";
system("PAUSE");
c.setColor('#');
z.rellenar();
c.setRadio(3);
c.pintar(&z);
z.mostrar();
//Ejemplo del circulo
system("PAUSE"); //Ejemplo de la Linea
l.setColor('.');
z.rellenar();
l.pintar(&z);
z.mostrar();
system("PAUSE");
//
Ejemplo de Polimorfismo
Figura *f;
Lienzo *li;
f = &l;
li = &z;
f->pintar(li);
li->mostrar();
system("PAUSE");
return EXIT_SUCCESS;
}
Metodología de la Programación II
Salida Esperada
* ^^^^^
^^@ ^^
^^ @
^^
^ @
^
^
+
^
^
^
^^
^^
^^
^^
^^^^^
Punto:(1,1), color:42
Bitmap:(2,2), color:64, contenido:001001001
Presione una tecla para continuar . . .
.
.
. ^^^^^
.^^
^^
^.
^^ .
^
.
^
.
^
^^
^
^^^
^^
^^^^^
Circulo:(8,8):5, color:94
Linea:(1,1),(8,8), color:46
Presione una tecla para continuar . . .
#####
##
##
#
#
#
#
#
#
##
##
#####
Presione una tecla para continuar . . .
.
.
.
.
.
.
.
.
Presione una tecla para continuar . . .
.
.
.
.
.
.
.
.
Nota: Se han eliminado algunos saltos de línea antes de cada "presione....." para que quepa el ejemplo.
Metodología de la Programación II
2) Conseguir que Figura y Lienzo muestren
comportamiento polimórfico dinámico: polimorfismo.
un
Realizar un programa de prueba, que cree figuras de varios tipos y las meta en un
array de referencias. Recorrer posteriormente el array con un bucle llamando al método
pintar (por ejemplo si el array se llama tabla, tabla[i]->pintar(l), siendo Lienzo *l).
Tanto Lienzo como Figura deben mostrar un comportamiento polimórfico. Todos
aquellos métodos en Lienzo y Figura que sean comunes a las subclases deben tener un
comportamiento polimórfico. Completa el programa llamando a cada uno de estos
métodos de la misma forma que el programa solicitado usando pintar(Lienzo *l).
3) Hacer que Figura y Lienzo sean clases abstractas
Consideramos que en nuestro sistema, un Lienzo y una Figura no se
deben poder instanciar como objetos. Realice las modificaciones necesarias para que el
compilador restrinja la instanciación de la clase Lienzo y Figura.
Realice un programa de prueba que instancie la clase Figura y compruebe
que el compilador da un error.
Si eliminamos la posibilidad de crear objetos de la clase Figura, ¿es esto
equivalente a quitar la clase de nuestro diseño? (responda a estas preguntas en
comentarios en el propio programa de prueba)
4) Destructores.
Queremos que todas nuestras clases tengan un destructor que muestre por
pantalla el mensaje:
“DESTRUCTOR:
objeto>]”
<NombreDeClase>[
<descripción
del
Es decir: la palabra DESTRUCTOR seguida del nombre de la clase a la que
pertenece el objeto que se está destruyendo y, en caso de que la clase sea una figura
concreta, de la descripción del objeto que se destruye.
En caso de ser necesario, el destructor deberá liberar la memoria que se ha
reservado para el objeto. (¡Ojo con las cadenas dinámicas!).
Haremos que estos mensajes se muestren por pantalla en base a una constante
definida con el precompilador:
#define DEPURACION
…
#ifdef DEPURACION
… Código para mostrar el mensaje …
#endif
Metodología de la Programación II
De modo que, si no se define la constante, la biblioteca de clases LibFiguras
no muestre mensajes cuando se ejecuten los destructores.
Realice un programa de prueba que genere un lienzo y una figura de cada
clase y que posteriormente los borre (delete) . Deberá mostrar los mensajes indicados
por cada clase.
Instrucciones de Entrega
La práctica deberá dejarse comprimida con winrar con el nombre:
Practica1_1_xxx.rar
en la cuenta de usuario.
donde xxx es el código de usuario asociado.
La práctica deberá contener dos directorios (LibFiguras y PruebaFiguras), en
LibFiguras estarán todas las clases de la librería, con un fichero .hpp y .cpp por
cada clase y un proyecto denominado Libfiguras para la generación de la librería
estática. En el otro directorio estarán todas las pruebas a realizar sobre la librería en .cpp
independientes con el numero del apartado que prueban: libPru_1,libpru_2,etc....
Las fechas de entrega serán desde el 13 al 25 de
defenderlas en clase de la siguiente forma:
-
Noviembre, siendo necesario
Dejar el fichero comprimido en la cuenta.
En el ordenador del profesor probar todos los ficheros de prueba.
Si funcionan adecuadamente se revisarán las librerías y programas de
prueba.
En caso de encontrarse errores se permitirá la reentrega dentro de fecha
En caso de errores graves no se considera apta.
Si la entrega final tiene errores leves, la calificación podrá ser del 50% ó 75% de
la parte que le corresponda a la práctica. Esta nota será validada cuando se
realice el examen de modificación hasta entonces la nota no será definitiva.
Es necesario superar todas las prácticas y haber asistido a un 70% de las clases
para tener apta la parte práctica de la asignatura, en caso contrario se puede optar
por examen final práctico.
Descargar