Prácticas de C++ Practica Nº 8 Informática II Fundamentos de Programación Prof. Dr. Paul Bustamante
ÍNDICE ÍNDICE... 1 1. INTRODUCCIÓN... 1 1.1 EJERCICIO 1: HERENCIA Y POLIMORFISMO I... 1 1.2 EJERCICIO 2: HERENCIA Y POLIMORFISMO II... 2 1.3 EJERCICIO 3: HERENCIA Y POLIMORFISMO III... 3 1.4 EJERCICIO 4: HERENCIA Y POLIMORFISMO IV... 4 1. Introducción. En la práctica de esta semana se trata de realizar unas clases utilizando herencia y funciones virtuales. Recuerda también que los guiones de las prácticas son más largos de lo que razonablemente se puede hacer en dos horas. Hay que evitar copiar los ejercicios de otra persona, principalmente porque así no se aprende a programar: a programar sólo se aprende programando 1.1 Ejercicio 1: Herencia y Polimorfismo I En este ejercicio se trata de utilizar una función virtual, viendo cómo actúa en función del objeto sobre el que se aplique, para lo cual vamos a partir del ejercicio de la práctica anterior. En main()se comprobarán como actúan las funciones virtuales A continuación se vuelve a mostrar la jerarquía de clases y la declaración de la clase base Empleado, de la cual partiremos: // Fichero Empleado.h // EJEMPLO DE FUNCIONES VIRTUALES #include <iostream.h> class Empleado { private: char name[80]; public: //constructores }; // función virtual. virtual void mostrar_info (){ cout << "Empleado" << endl; } Empleado Operario Directivo Oficial Tecnico Los pasos a seguir son: 1. Introduce una variable miembro en la clase base que contenga el nombre del empleado (de número fijo de caracteres y sin reserva dinámica de memoria). Dicha variable será privada de forma que las clases derivadas no puedan acceder a dicho valor. char name[80]; 2. Crea los constructores necesarios para poder indicar el nombre. Los constructores de la clase base serán los únicos que mediante la función strcpy() asignarán el nombre. El resto de constructores deberán llamar a los correspondientes de su clase base. 3. Añade una función miembro pública a la clase base (Empleado) de forma que devuelva el nombre del empleado:
Practica Nº 8 Programación en C++ Pág. 2 char *getname(); 4. Construye todas las clases de forma que sólo tengan que pasarle el nombre a la variable heredada. Por ahora no tendrán otras variables. 5. Redefina la función mostrar_info() en todas las demás clases derivada para que escriba el nombre del empleado. Deberá utilizar la función getname() para poder obtener el nombre, ya que dicha variable es privada. 6. Agregue el siguiente código en la función principal main(); éste es el código de creación de los empleados: Empleado Rafa("Rafa"); Directivo Mario("Mario"); Operario Anton("Anton"); Oficial Luis("Luis"); Tecnico Pablo("Pablo"); // El tipo de objeto apuntado por un puntero a la clase base // determina la función que es llamada Empleado *pe; cout << "\nherencia y Polimorfismo:\n" << endl; pe = &Rafa; pe->mostrar_info(); pe = &Mario; pe-> mostrar_info (); pe = &Anton; pe-> mostrar_info (); pe = &Luis; pe-> mostrar_info (); pe = &Pablo; pe-> mostrar_info (); cout << "Ya he terminado." << endl; 7. Ahora compile el programa y ejecútelo. Observe lo que ocurre. Después elimine la palabra virtual en la declaración de la función mostrar_info() de la clase base Empleado, observando la diferencia en la salida del programa. Se trata de un claro caso de polimorfismo. Una vez comprendida dicha diferencia vuelve a incluir de nuevo la palabra virtual y pase al siguiente ejercicio. 1.2 Ejercicio 2: Herencia y Polimorfismo II El objetivo de este ejercicio consiste en añadir algunas variables miembro, con el fin de distinguir el manejo de las variables miembro private respecto de las protected. Además se debe crear una función que muestre toda la información que se dispone de un empleado. Para ello se debe partir del ejercicio anterior y modificarlo adecuadamente. Con el fin de evitar copiar todos los ficheros anteriores, vamos a continuar con el mismo proyecto. Las modificaciones a realizar son: 1. Introduzca una variable miembro en la clase base que contenga el salario del empleado. Dicha variable será privada de forma que las clases derivadas no puedan acceder a dicho valor. long salario; 2. Añada la variable miembro titulo a la clase Directivo. Esta variable es una cadena de caracteres de tamaño fijo y sin reserva dinámica de memoria, además se puede definir como protected. char titulo[80];
Practica Nº 8 Programación en C++ Pág. 3 3. Añada la variable miembro puesto a la clase Operario. Esta variable es una cadena de caracteres de tamaño fijo y sin reserva dinámica de memoria, además se puede definir como protected para que las clases derivadas de la clase Operario puedan acceder a ella. char puesto[80]; 4. Crea los constructores necesarios para poder indicar el salario, el título en caso de que sea un directivo o el puesto en el caso de un operario. 5. Crea la función miembro pública GetSalario() de la clase base Empleado, que devuelva el salario de cada empleado. long GetSalario(); 6. La función virtual mostrar_info()) debe muestrar por pantalla toda la información almacenada de cada empleado, su cargo, su nombre, su salario, y además su puesto o título, dependiendo de si se trata de un operario o un directivo. 7. En el programa principal main() se creará un array de 6 punteros a empleados. Se definirá previamente el número de empleados mediante un define. #define NUM_EMPLEADOS 6 8. A continuación en el mismo fichero crea los empleados mediante llamadas a cada uno de los constructores. Empleado* ListaEmpleados[NUM_EMPLEADOS]; ListaEmpleados[0] = new Directivo("Maria Artola", 35000, "Economista"); ListaEmpleados[1] = new Directivo("Juan Perez", 38000, "Ingeniero"); ListaEmpleados[2] = new Oficial("Pedro Egia", 18000, "Oficial 1"); ListaEmpleados[3] = new Oficial("Luisa Penia", 15000, "Oficial 2"); ListaEmpleados[4] = new Tecnico("Javier Ramos", 19500, "Soldador"); ListaEmpleados[5] = new Tecnico("Amaia Bilbao", 12000, "Electricista"); 9. Por último, después de crear los objetos se debe llamar a la función mostrar_info() de cada empleado, para mostrar su información por pantalla. for(int i=0;i<num_empleados;i++) ListaEmpleados[i]->mostrar_info(); 10. Después de haber probado el correcto funcionamiento del ejercicio, tenemos modificar el programa para que pida al usuario los empleados que se deseen crear y que pida de forma automática (sobrecargando el operador >> ) todos los datos del nuevo objeto creado. 1.3 Ejercicio 3: Herencia y Polimorfismo III El objetivo de este ejercicio consiste en utilizar una variable miembro que sea un objeto de otra clase, para ello se parte del ejercicio 2. En este punto es mejor crear un proyecto nuevo y copiar todos los ficheros *.cpp y *.h del ejercicio anterior y agregarlos al nuevo proyecto. Las modificaciones a realizar son: 1. En un fichero llamado fecha.h crea una nueva clase llamada Fecha con tres variables miembro privadas de tipo long: dia, mes y anno. class Fecha{ private: long dia; long mes; long anno; };
Practica Nº 8 Programación en C++ Pág. 4 2. A esta clase le debes añadir un constructor general con tres argumentos cuyos valores por defecto sean 1, 1 y 1900. 3. A la clase Empleado le debes añadir una nueva variable miembro private que represente la fecha de contratación del empleado, FechaContr. Dicha variable será pues un objeto de la clase Fecha. 4. Modifica los constructores de las clases base y derivadas de modo que sean capaces de inicializar la fecha de contratación de cada clase de empleado. 5. Añade la función miembro GetFecha() a la clase Empleado, de forma que devuelva la fecha de contratación. Fecha GetFecha(); 6. Modifica las funciones mostrar_info(), de forma que, además de la información que mostraban en el ejercicio 3, puedan mostrar por pantalla la fecha de contratación, haciendo uso de la función GetFecha() (debes sobrecargar el operador << en la clase Fecha para que puedas imprimirla directamente, haciendo cout <<... << GetFecha() <<... << endl ). 7. Probar estos cambios ejecutando el programa principal, sin más que modificar la parte correspondiente a los constructores. Desde main() se crearán así los objetos (con la fecha de contratación. Aquél que no tenga, le asignará la de defecto: 1/1/1900): Lista[0] = new Directivo("Mario",2500,"Ingeniero",Fecha(10,11,1993)); Lista[1] = new Oficial("Anton",1800,"Oficial 1"); Lista[2] = new Oficial("Luis",2000,"Oficial 2",Fecha(1,5,1998)); Salida por consola 1.4 Ejercicio 4: Herencia y Polimorfismo IV En este ejercicio se trata de utilizar variables miembro estáticas. Copia los ficheros *.h y *.cpp del ejercicio 3 y crea con ellos un nuevo proyecto llamado Ejer4. Las modificaciones a realizar son: 1. Añade a la clase Empleado tres variables miembro static, que sean los beneficios de la empresa, el número de Directivos y la Fecha Actual. Deben ser static porque son valores únicos para toda la empresa, es decir no son particulares de cada empleado. Además deben ser protected para que todas las clases derivadas de Empleado puedan acceder a ellas. static long Beneficios; static long NumDirectivos; static Fecha FechaActual; Recuerda que la inicialización de las variables static se hacen de forma global (una vez): long Empleado::Beneficios = 500000; long Empleado:: NumDirectivos = 0; Fecha Empleado::FechaActual=Fecha(21,5,2002); void main(void) {... }
Practica Nº 8 Programación en C++ Pág. 5 2. Cada vez que se crea un nuevo directivo la variable NumDirectivos se debe incrementar en 1, mientras que cuando se destruye se debe decrementar en 1. Esto significa que se debe programar el destructor de la clase Directivos, a pesar de no haber realizado reserva dinámica de memoria (debes declarar el destructor de Empleado como virtual ). 3. Crea la función calcular_pago() de forma que incremente a todos los empleados un 2.5% de su salario por cada trienio que lleve en la empresa y que para un directivo añada además el 5% del reparto de los beneficios entre todos los directivos. En la clase Fecha haz una funcion amiga trienios() que según las fechas que se le pasen como argumentos, devuelva el número de trienios, comparando días, mes y años: friend int trienios(fecha &fact, Fecha &fing){... } 4. Modifica el programa principal ( main() ) para que se vean reflejados todos los cambios de este ejercicio.