elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Usando Git para manipular el directorio de trabajo, el índice y commits (segunda parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Tengo una duda sobre redefinición de funciones virtuales en C++
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Tengo una duda sobre redefinición de funciones virtuales en C++  (Leído 2,026 veces)
theluigy13etv

Desconectado Desconectado

Mensajes: 179


Primero se hace, después se mejora


Ver Perfil
Tengo una duda sobre redefinición de funciones virtuales en C++
« en: 20 Febrero 2015, 17:01 pm »

Hola :) , estoy intentando hacer el juego de pacman en modo consola en mis ratos de ocio y de pasada me voy recordando algunas cosas que ya me estaba olvidando y afianzando otros conceptos sobre la programación orientada a objetos.

Expondré lo que hice hasta ahora y luego mi duda. No es tanto sobre el código sino más que todo en cuanto a cómo funciona lo de la redefinición de una función virtual.

Resulta que tengo tres clases: PERSONAJE, PACMAN, FANTASMA:

Clase Personaje:
Código
  1. class PERSONAJE {
  2.   private:
  3.      int x, y;   // Coordenadas
  4.      int simbolo;
  5.  
  6.   public:
  7.      PERSONAJE(int = 1, int = 1, int = 1);
  8.      void setX(int);
  9.      void setY(int);
  10.      void setSimbolo(int);
  11.      int getX();
  12.      int getY();
  13.      int getSimbolo();
  14.      virtual void mover(int);
  15.      void pintar();
  16.      void borrar();
  17. };
  18.  
  19. /*
  20. void PERSONAJE::PERSONAJE(int x, int y, char simbolo) {
  21.    this->setX(x);
  22.    this->setY(y);
  23.    this->setSimbolo(simbolo);
  24. }
  25. */
  26.  
  27. PERSONAJE::PERSONAJE(int _x, int _y, int _simbolo) : x(_x), y(_y), simbolo(_simbolo) {
  28.   this->pintar();
  29. }
  30.  
  31. void PERSONAJE::setX(int x) {
  32.   this->x = (x > 0 ? x : 1);
  33.   // x = (x > 0 ? x : 1); // Cuidado con este error logico, alli no estaria modificando al atributo
  34. }
  35.  
  36. void PERSONAJE::setY(int y) {
  37.   this->y = (y > 0 ? y : 1);
  38. }
  39.  
  40. void PERSONAJE::setSimbolo(int simbolo) {
  41.   this->simbolo = simbolo;
  42. }
  43.  
  44. int PERSONAJE::getX() {
  45.   return this->x;
  46. }
  47.  
  48. int PERSONAJE::getY() {
  49.   return this->y;
  50. }
  51.  
  52. int PERSONAJE::getSimbolo() {
  53.   return this->simbolo;
  54. }
  55.  
  56. void PERSONAJE::mover(int tecla) {
  57.  
  58.   if (tecla == NADA) {
  59.      return;
  60.   }
  61.   else {
  62.      this->borrar();
  63.  
  64.      if (tecla == IZQUIERDA) {
  65.         if (x > LIMITE_IZQUIERDO + 1) x--;
  66.      }
  67.  
  68.      if (tecla == DERECHA) {
  69.         if (x < LIMITE_DERECHO - 1) x++;
  70.      }
  71.  
  72.      if (tecla == ABAJO) {
  73.         if (y < LIMITE_INFERIOR - 1) y++;
  74.      }
  75.  
  76.      if (tecla == ARRIBA) {
  77.         if (y > LIMITE_SUPERIOR + 1) y--;
  78.      }
  79.  
  80.      this->pintar();
  81.   }
  82. }
  83.  
  84. void PERSONAJE::pintar() {
  85.   gotoxy(x, y);
  86.   cout << (char)getSimbolo();
  87. }
  88.  
  89. void PERSONAJE::borrar() {
  90.   gotoxy(x, y);
  91.   cout << " ";
  92. }
  93.  
  94.  



Clase Pacman:
Código
  1. class PACMAN : public PERSONAJE {
  2.   private:
  3.  
  4.   public:
  5.      PACMAN(int = LIMITE_IZQUIERDO + 1, int = LIMITE_SUPERIOR + 1, int = 1);
  6.      // No redefinimos el metodo pintar() asi que se llamara al de la superclase
  7. };
  8.  
  9. PACMAN::PACMAN(int x, int y, int simbolo) : PERSONAJE(x, y, simbolo) {
  10. }
  11.  



Clase Fantasma:
Código
  1. class FANTASMA : public PERSONAJE {
  2.   private:
  3.  
  4.   public:
  5.      FANTASMA(int = (LIMITE_IZQUIERDO + LIMITE_DERECHO) / 2, int = (LIMITE_SUPERIOR + LIMITE_INFERIOR) / 2, int = 1);
  6.      void mover();
  7. };
  8.  
  9. FANTASMA::FANTASMA(int x, int y, int simbolo) : PERSONAJE(x, y, simbolo) {
  10. }
  11.  
  12. void FANTASMA::mover() {
  13.   int aleatorio = rand() % 4;
  14.  
  15.   this->borrar();
  16.  
  17.   switch (aleatorio) {
  18.      case 0:
  19.         if (getX() > LIMITE_IZQUIERDO + 1) setX(getX() - 1);
  20.         break;
  21.  
  22.      case 1:
  23.         if (getX() < LIMITE_DERECHO - 1) setX(getX() + 1);
  24.         break;
  25.  
  26.      case 2:
  27.         if (getY() < LIMITE_INFERIOR - 1) setY(getY() + 1);
  28.         break;
  29.  
  30.      case 3:
  31.         if (getY() > LIMITE_SUPERIOR + 1) setY(getY() - 1);
  32.         break;
  33.   }
  34.  
  35.   gotoxy(getX(), getY());
  36.   this->pintar(); // Llama al método heredado pintar
  37. }
  38.  

Algunas constantes en mi código:
Código
  1. // Direccion
  2. #define ARRIBA 105
  3. #define ABAJO 107
  4. #define IZQUIERDA 106
  5. #define DERECHA 'l'
  6.  
  7. // Limites
  8. #define LIMITE_SUPERIOR 2
  9. #define LIMITE_INFERIOR 23
  10. #define LIMITE_DERECHO 70
  11. #define LIMITE_IZQUIERDO 20
  12.  
  13. #define NADA 0
  14.  


Mi duda está en lo siguiente:
En mi clase base PERSONAJE defino una función virtual mover(int) la cual tiene un parámetro. Luego, declado dos clases derivadas: PACMAN y FANTASMA.
Dentro de la clase PACMAN (por el momento) no declaro ninguna otra función por lo que concluyo que va a heredar las ya declaradas en la clase base PERSONAJE.
Dentro de la clase FANTASMA estoy declarando una función llamada mover() sin parámetros. Esta función tiene el mismo nombre que la función virtual declarada en la clase base PERSONAJE pero se diferencia en que no tiene ningún parámetro. Entonces ante la duda de si en este caso estoy redefiniendo la función perteneciente al padre, encontré la siguiente información:

Citar
Para redefinir una función virtual en una clase derivada, las declaraciones en la clase base y en la derivada deben coincidir en cuanto a número y tipo de los parámetros. Excepcionalmente pueden diferir en el tipo devuelto.

Entonces según esto, la función mover() perteneciente a la clase hija FANTASMA es diferente a la función mover(int) de la clase padre PERSONAJE (por su parámetro) por lo que podría concluir que no se estaría redefiniendo nada sino que, la clase FANTASMA contaría con dos funciones miembro diferentes:
    - mover()    : Obtenida por la herencia y declarada en el padre PERSONAJE
    - mover(int) : Declarada en la clase hija FANTASMA

Además de las otras funciones heredadas del padre: getX(), getY(), getSimbolo(), setX(int), setY(int), setSimbolo(int), .. , borrar(), pintar().


Siendo todo esto así, creo que no debería tener problemas al realizar llamadas tanto a las funciones mover() y mover(int) desde un objeto de la clase FANTASMA pero cuando realizo dichas llamadas, el compilador me genera un error márcandome esta llamada: f1.mover(IZQUIERDA);:


Código
  1. FANTASMA f1;
  2. f1.mover();
  3. f1.mover(IZQUIERDA);
  4.  




No sé si me estoy haciendo demasiados rodeos  ;D . Espero que me haya dejado entender. Gracias a los que se tomen la molestia de leer y de ayudarme a entender el por qué me sale ese error :D . (Si pudieran también comentar sobre mi código, acepto sugerencias y críticas para poder mejorar. Respecto a la biblioteca conio tengo claro que no es estándar pero en este caso lo que trato más que todo es centrarme en aplicar correctamente los conceptos de la POO)


« Última modificación: 20 Febrero 2015, 17:09 pm por theluigy13etv » En línea

_Enko


Desconectado Desconectado

Mensajes: 538



Ver Perfil WWW
Re: Tengo una duda sobre redefinición de funciones virtuales en C++
« Respuesta #1 en: 20 Febrero 2015, 19:49 pm »

Haz el metodo virtual que quieres sobreescribir en la clase derivada como "override".  Si no hay nada que sobreescribir, el compilador tendría que protestar. De esa manera te aseguras que estas sobreescribiendo un metodo de la clase Padre.

No solo importa el nombre del metodo, sino los argumentos y el tipo devuelto.
move(void) no es lo mismo que move(int).


Saludos.




En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Funciones virtuales
Programación C/C++
eleon 2 2,100 Último mensaje 29 Julio 2012, 22:51 pm
por eleon
¿Pequeña duda sobre las máquinas virtuales? « 1 2 »
Windows
theluigy13etv 11 9,366 Último mensaje 7 Septiembre 2012, 01:26 am
por kaiserr
duda sobre estructuras y funciones
Programación C/C++
asdavid 3 2,848 Último mensaje 29 Noviembre 2012, 00:01 am
por durasno
Duda sobre ficheros en funciones
Programación C/C++
muymuyperdido 4 2,966 Último mensaje 23 Diciembre 2012, 15:43 pm
por muymuyperdido
Consulta acerca de posición/distancia de funciones virtuales en una clase
Programación C/C++
BloodSharp 2 1,790 Último mensaje 16 Diciembre 2018, 18:39 pm
por BloodSharp
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines