¿Duda sobre la sobreescritura de una función miembro en una clase derivada?

Iniciado por theluigy13etv, 21 Julio 2013, 07:44 AM

0 Miembros y 1 Visitante están viendo este tema.

theluigy13etv

Hola a todos, necesito una pequeña ayuda, resulta que conozco un poco de Java así que me animé a aprender C++ y ahora estoy practicando lo que es la herencia y el polimorfismo. Estoy que me tranqueo en la parte de la sobreescritura de métodos.

Verán, primero definí una clase base llamada Persona con dos atributos: "nombre" y "edad", además con 5 métodos públicos: "setNombre", "setEdad", "getNombre", "getEdad" y "metodo".

Luego definí dos clases derivadas de la clase Persona. Las clases derivadas son Alumno y Docente. Ambas clases con sus propios métodos set y get para manipular sus propios atributos (datos miembro) . Luego, en las clases derivadas Alumno y Docente redefiní la función miembro llamada "metodo" que heredaron de la clase base Persona.

Al final, en el método main, creé los objetos correspondientes a cada clase y luego hice que un puntero p de tipo de la clase base Persona ( Persona *p ) apunte a cada objeto creado para llamar a la función miembro "metodo" . Pensé que en cada caso se ejecutaría la función miembro correcta correspondiente a cada objeto pero al ver los resultados en pantalla me doy con la sorpresa de que en todos los casos se ejecuta la función miembro correspondiente a la clase base Persona. Tal vez estoy cometiendo un error y no sé como solucionarlo, espero que alguien me pueda ayudar, muchas gracias  :)

Código (C++) [Seleccionar]

#include <iostream>
#include <string>

using namespace std;

// Clase PERSONA
class Persona {

public:
  // Constructor con argumentos por defecto
  Persona(string nombre = "", const int edad = 0);
 
  // Métodos
  void setNombre(string nombre);
  void setEdad(const int edad);
  string getNombre();
  int getEdad();
 
  void metodo();;

private:
  string nombre;
  int edad;  
};

Persona::Persona(string nombre, const int edad) : nombre(nombre), edad(edad < 0 ? 0 : edad) {
  /*
  this->setNombre(nombre);
  this->setEdad(edad);
  */
}

void Persona::setNombre(string nombre) {
  this->nombre = nombre;  
}

void Persona::setEdad(const int edad) {
  this->edad = (edad < 0) ? 0 : edad;  
}

string Persona::getNombre() {
  return this->nombre;  
}

int Persona::getEdad() {
  return this->edad;  
}

void Persona::metodo() {
  cout << "Metodo de la clase base Persona" << endl;
}


// CLASE ALUMNO
class Alumno : public Persona {
 
public:
  // Constructor con argumentos por defecto
  Alumno(string nombre = "", int edad = 0, string codigo = "");
 
  void setCodigo(string codigo);
  string getCodigo();
 
  void metodo();
 
private:
  string codigo;
};

Alumno::Alumno(string nombre, int edad, string codigo)
  : Persona(nombre, edad), codigo(codigo) {
}

void Alumno::setCodigo(string codigo) {
  this->codigo = codigo;  
}
 
string Alumno::getCodigo() {
  return codigo;  
}
 
void Alumno::metodo() {
  cout << "Método redefinido de la clase derivada Alumno" << endl;  
}

// CLASE DOCENTE
class Docente : public Persona {
 
public:
  // Constructor con tres argumentos por defecto
  Docente(string nombre = "", int edad = 0, float salario = 0.0);
 
  void setSalario(float salario);
  float getSalario();
 
  void metodo();
 
private:
  float salario;
};

Docente::Docente(string nombre, int edad, float salario)
  : Persona(nombre, edad), salario(salario < 0.0 ? 0.0 : salario) {
}

void Docente::setSalario(float salario) {
  this->salario = (salario < 0.0) ? 0.0 : salario;  
}

float Docente::getSalario() {
  return salario;  
}

void Docente::metodo() {
  cout << "Método redefinido de la clase base Docente" << endl;  
}

int main()
{  
  Persona *p;
  cout << "PERSONAS:" << endl;
  p = new Persona("Dennis Ritchie", 19);      
  p->metodo();
 
  cout << "\nALUMNOS:" << endl;
  p = new Alumno("Bjarne Stroustrup", 22, "20080541x");
  p->metodo();
 
  p = new Alumno("Esther Noemí", 19, "21130515h");
  p->metodo();
 
  cout << "\nDOCENTES:" << endl;
  p = new Docente("Riquelmer Vazques", 58, 1500.0);
  p->metodo();
 
  cin.get();
  return 0;  
}

amchacon

Creo que te has equivocado y has puesto la etiqueta de java (o otro lenguaje, el caso esque ese resaltado sintáctico no me suena).

Si quieres que tu función se sobreescriba en la herencia, debes hacerla "virtual" en la clase base:

Código (cpp) [Seleccionar]
virtual void metodo();

Ahora sí debería funcionar  ;)
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

theluigy13etv

Muchas gracias amchacon, ya solucioné el problema, tal y como dijiste, tuve que declarar la función de la clase base como virtual para que luego de que lo sobrescriba en las clases bases e invoque a esa función usando un puntero de la clase base, se ejecute la función correspondiente a la clase derivada.  :)  :)

theluigy13etv

Muchas gracias amchacon, ya solucioné el problema, tal y como dijiste, tuve que declarar la función de la clase base como virtual para que luego de que lo sobrescriba en las clases derivadas e invoque a esa función usando un puntero de la clase base, se ejecute la función correspondiente a la clase derivada.  :)  :)