Secuencia de Ejecución de Constructores y Destructores
Observe el siguiente programa:
#include<iostream.h>
class primero { int p_a; public: primero(int); ~primero(); };
primero::primero(int x) { p_a=x; cout << "primero, x = " << p_a << endl; }
primero::~primero() { cout << "Se destruyó el primero" << endl; }
class segundo: public primero { int s_a; public: segundo(int); ~segundo(); };
segundo::segundo(int x): primero(x-1) { s_a=x; cout << "segundo, x = " << s_a << endl; }
segundo::~segundo() { cout << "Se destruyó el segundo" << endl; }
class tercero: public segundo { int t_a; public: tercero(int); ~tercero(); };
tercero::tercero(int x): segundo(x-1) { t_a=x; cout << "tercero, x = " << t_a << endl; }
tercero::~tercero() { cout << "Se destruyó el tercero" << endl; }
void main(void) { tercero p(7); cout << endl; }
/* Al ejecutar el programa se obtiene:
primero, x = 5 segundo, x = 6 tercero, x = 7
Se destruyó el tercero Se destruyó el segundo Se destruyó el primero */
Como se ve, en el caso de los Constructores, el compilador C++, primero ejecuta el Constructor de la clase base y luego el Constructor de la clase derivada. Sin embargo, cuando se trata de Destructores, primero se ejecuta el Destructor de la clase derivada y luego el de la clase base.
Redefinición de elementos en una clase derivada
Una clase derivada puede definir atributos y métodos con el mismo nombre que estos elementos tiene en la clase base. En estos casos el número de atributos o métodos anula a su correspondiente definido en la clase base, esto se conoce con el nombre de "overriding".
Ejemplo:
#include<iostream.h> #include<string.h>
class Persona { char *Nombre; char *Direccion; int Edad; public: Persona(char *, char *, int); ~Persona(); void DefineNombre(char *); void DefineDireccion(char *); void DefineEdad(int); char *DameNombre(void); char *DameDireccion(void); int DameEdad(void); void MuestraDatos(void); };
Persona::Persona(char *Nomb, char *Dir, int Ed) { Nombre = new char[strlen(Nomb)+1]; strcpy(Nombre,Nomb); Direccion = new char[strlen(Dir)+1]; strcpy(Direccion,Dir); Edad = Ed; }
Persona::~Persona() { delete Nombre; delete Direccion; }
void Persona::DefineNombre(char *Nomb) { Nombre = new char[strlen(Nomb)+1]; strcpy(Nombre,Nomb); }
void Persona::DefineDireccion(char *Dir) { Direccion = new char[strlen(Dir)+1]; strcpy(Direccion,Dir); }
void Persona::DefineEdad(int Ed) { Edad = Ed; }
char *Persona::DameNombre(void) { return Nombre; }
char *Persona::DameDireccion(void) { return Direccion; }
int Persona::DameEdad(void) { return Edad; }
void Persona::MuestraDatos(void) { cout << "Nombre : " << Nombre << endl; cout << "Dirección : " << Direccion << endl; cout << "Edad : " << Edad << endl; }
class Alumno : public Persona { int Grado; char *Colegio; public: Alumno(char *, char *, int, int, char *); ~Alumno(); void DefineGrado(int); void DefineColegio(char *); void MuestraDatos(void); //Redefinición ("Overriding") };
Alumno::Alumno(char *N, char *D, int E, int G, char * C) : Persona(N, D, E) { Grado = G; Colegio = new char[strlen(C)+1]; strcpy(Colegio,C); }
Alumno::~Alumno() { delete Colegio; }
void Alumno::DefineGrado(int G) { Grado = G; }
void Alumno::DefineColegio(char * C) { Colegio = new char[strlen(C)+1]; strcpy(Colegio,C); }
void Alumno::MuestraDatos(void) { cout << "Nombre : " << DameNombre() << endl; cout << "Dirección : " << DameDireccion() << endl; cout << "Edad : " << DameEdad() << endl; cout << "Grado : " << Grado << endl; cout << "Colegio : " << Colegio << endl; }
void main (void) { char buff[30]; Persona P("Juan Lopez", "Av. ABC #123", 6); Alumno A("Maria Ruiz", "AV. XYZ #555", 7, 2,"El Buen Alumno");
P.MuestraDatos(); cout << endl; A.MuestraDatos(); }
/*La ejecución de este programa muestra:
Nombre : Juan Lopez Dirección : Av. ABC #123 Edad : 6
Nombre : María Ruiz Dirección : AV. XYZ #555 Edad : 7 Grado : 2 Colegio : El Buen Alumno */
En el ejemplo anterior se puede observar que el método "MuestraDatos" es redefinido en clase Alumno. Sin embargo, vemos que en esta redefinición se está repitiendo el código utilizado en el método "Muestra Datos" de la clase Persona, para evitar esto se puede hacer uso del operador de resolución de ambito.
Ejemplo:
void Alumno::MuestraDatos(void)
{ Persona::MuestraDatos();
cout << "Grado : " << Grado << endl;
cout << "Colegio : " << Colegio << endl;
}
![]() |
![]() ![]() |