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 color 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
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 mathh) 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 Libfigurashpp, que incluya todas las cabeceras creadas para los módulos de esta biblioteca
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 PruebaLibCpp 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,'@'); zrellenar(' '); // Pinta dos puntos, un bitmap ppintar(&z); // y un circulo de radio 4 p1pintar(&z); bpintar(&z); cpintar(&z); zmostrar(); cout << pdescripcion()<< "\n"; cout << bdescripcion()<< "\n"; system("pause"); //Limpia el lienzo zrellenar(); //Dibuja un circulo y una linea csetradio(5); //cambio radio csetpos(pos3);//cambio posicion cpintar(&z); lpintar(&z); zmostrar(); cout << cdescripcion()<< "\n"; cout << ldescripcion()<< "\n"; system("pause"); csetcolor('#'); zrellenar(); csetradio(3); cpintar(&z); zmostrar(); //Ejemplo del circulo system("pause"); //Ejemplo de la Linea lsetcolor(''); zrellenar(); lpintar(&z); zmostrar(); system("pause"); } // Ejemplo de Polimorfismo Figura *f; Lienzo *li; f = &l; li = &z; f->pintar(li); li->mostrar(); system("pause"); return EXIT_SUCCESS;
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
2) Conseguir que Figura y Lienzo muestren un comportamiento polimórfico dinámico: polimorfismo 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: <NombreDeClase>[ <descripción del objeto>] 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
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_xxxrar 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 Noviembre, siendo necesario defenderlas en clase de la siguiente forma: - 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