DE HOJA INGENIERO EN COMPUTACIÓN ESIME CULHUACAN ESTRUCTURADA FECHA DIA NOMBRE DEL ALUMNO 5 1 MES AÑO ASIGNATURA Apellido paterno No. BOLETA PROGRAMACION ORIENTADA A OBJETOS Nombre (s) Apellido materno GRUPO PROFESOR ING. R. OSORNIO PRÁCTICA No. 25 HERENCIA PARTE V I.- OBJETIVO: Al término de la practica el alumno podrá: - Hacer programas con herencia II.- MATERIAL Y EQUIPO: 1 1 1 1 1 EQUIPO DE CÓMPUTO CPU Marca_____________ Mod. _________________ N°. ______________ Monitor Marca_____________ Mod. _________________ N° ______________ Teclado Marca_____________ Mod. _________________ N°. ______________ DISKETE DE 3.5 “ III.- INTRODUCCIÓN TEÓRICA. Funciones virtuales: El ejemplo anterior demuestra algunas de las posibilidades del polimorfismo, pero tal vez sería mucho más interesante que cuando se invoque a una función que se superpone en la clase derivada, se llame a ésta última función, la de la clase derivada. En nuestro ejemplo, podemos preferir que al llamar a la función "VerNombre" se ejecute la versión de la clase derivada en lugar de la de la clase base. Esto se consigue mediante el uso de funciones virtuales. Cuando en una clase declaramos una función como virtual, y la superponemos en alguna clase derivada, al invocarla usando un puntero de la clase base, se ejecutará la versión de la clase derivada. LABORATORIO DE PROGRAMACION ORIENTADA A OBJETOS ROS PRACTICA 25 PAGINA 1 Sintaxis: virtual <tipo> <nombre_función>(<lista_parámetros>) [{}]; Modifiquemos en el ejemplo anterior la declaración de la clase base "Persona". class Persona { public: Persona(char *n) { strcpy(nombre, n); } virtual char *VerNombre(char *n) { strcpy(n, nombre); return n;} protected: char nombre[30]; }; Ahora ejecutemos el programa de nuevo, veremos que la salida es ahora diferente: Emp: Carlos Est: Jose Presione cualquier tecla para continuar . . . Ahora, al llamar a "Pepito->VerNombre(n)" se invoca a la función "VerNombre" de la clase "Estudiante", y al llamar a "Carlos->VerNombre(n)" se invoca a la función de la clase "Empleado". Una vez que una función es declarada como virtual, lo seguirá siendo en las clases derivadas, es decir, la propiedad virtual se hereda. Si la función virtual no se define exactamente con el mismo tipo de valor de retorno y el mismo número y tipo de parámetros que en la clase base, no se considerará como la misma función, sino como una función superpuesta. Este mecanismo sólo funciona con punteros y referencias, usarlo con objetos no tiene sentido. Destructores virtuales: Supongamos que tenemos una estructura de clases en la que en alguna de las clases derivadas exista un destructor. Un destructor es una función como las demás, por lo tanto, si destruimos un objeto referenciado mediante un puntero a la clase base, y el destructor no es virtual, estaremos llamando al destructor de la clase base. Esto puede ser desastroso, ya que nuestra clase derivada puede tener más tareas que realizar en su destructor que la clase base de la que procede. Por lo tanto debemos respetar siempre ésta regla: si en una clase existen funciones virtuales, el destructor debe ser virtual. Constructores virtuales: Los constructores no pueden ser virtuales. Esto puede ser un problema en ciertas ocasiones. Por ejemplo, el constructor copia no hará siempre aquello que esperamos que haga. En general no debemos usar el constructor copia cuando usemos punteros a clases base. Para solucionar este inconveniente se suele crear una función virtual "clonar" en la clase base que se superpondrá para cada clase derivada. LABORATORIO DE PROGRAMACION ORIENTADA A OBJETOS ROS PRACTICA 25 PAGINA 2 IV. DESARROLLO EL ALUMNO SEGUIRÁ LA SECUENCIA INDICADA, DESCRIBIENDO EN CADA INCISO LOS PASOS QUE SIGA: 4.1. Realice un programa con Programación orientada a objetos en C++ con Class: "PROGRAMA QUE tenga datos miembros privados , una funcion publica donde se utilice : LABORATORIO DE PROGRAMACION ORIENTADA A OBJETOS ROS PRACTICA 25 PAGINA 3 #include <iostream.h> #include <stdlib.h> #include <string.h> class Persona { public: Persona(char *n) { strcpy(nombre, n); } Persona(const Persona &p); virtual char *VerNombre(char *n) { strcpy(n, nombre); return n;} virtual Persona* Clonar() { return new Persona(*this);} protected: char nombre[30]; }; Persona::Persona(const Persona &p) { strcpy(nombre, p.nombre); cout << "Per: constructor copia." << endl; } class Empleado : public Persona { public: Empleado(char *n) : Persona(n) {} Empleado(const Empleado &e); char *VerNombre(char *n) { strcpy(n, "Emp: "); strcat(n, nombre); return n;} virtual Persona* Clonar() { return new Empleado(*this);} }; Empleado::Empleado(const Empleado &e) : Persona(e) { cout << "Emp: constructor copia." << endl; } class Estudiante : public Persona { public: Estudiante(char *n) : Persona(n) {} Estudiante(const Estudiante &e); char *VerNombre(char *n) { strcpy(n, "Est: "); strcat(n, nombre); return n;} virtual Persona* Clonar() { return new Estudiante(*this);} }; Estudiante::Estudiante(const Estudiante &e) : Persona(e) { cout << "Est: constructor copia." << endl; } int main() { char n[40]; Persona *Pepito = new Estudiante("Jose"); Persona *Carlos = new Empleado("Carlos"); Persona *Gente[2]; cout << Carlos->VerNombre(n) << endl; cout << Pepito->VerNombre(n) << endl; Gente[0] = Carlos->Clonar(); cout << Gente[0]->VerNombre(n) << endl; Gente[1] = Pepito->Clonar(); cout << Gente[1]->VerNombre(n) << endl; delete Pepito; delete Carlos; delete Gente[0]; delete Gente[1]; system("pause"); return 0; } LABORATORIO DE PROGRAMACION ORIENTADA A OBJETOS ROS PRACTICA 25 PAGINA 4 V. CUESTIONARIO (TRABAJO COMPLEMENTARIO). 1. – ¿ Explique que hacen las funciones virtuales ? 2.- ¿ Explique la sintaxis ? VI.- CONCLUSIONES Y OBSERVACIONES: LABORATORIO DE PROGRAMACION ORIENTADA A OBJETOS ROS PRACTICA 25 PAGINA 5