Funciones virtuales

Iniciado por eleon, 29 Julio 2012, 13:04 PM

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

eleon

Buenas, tengo dos dudillas acerca de las funciones virtuales, a ver si me las podéis resolver:

Código (cpp) [Seleccionar]
class ClaseA
{
public:
  virtual void funcion () {};

};

class ClaseB : public ClaseA
{
  void funcion () {};
};

int main ()
{
  ClaseA *objeto = new ClaseB;

}


Hemos creado un objeto de tipo "ClaseA" pero hemos reservado memoria del tamaño "ClaseB". Y al declarar "funcion" como virtual, cada vez que la llamemos estaremos accediendo a la que hay en la clase que hereda y no a la de la clase base. Pero, ¿de qué nos sirve exactamente esto?. ¿No sería lo mismo que declarar el objeto de tipo ClaseB y sobrecargar la función sin añadir "virtual"?:

Código (cpp) [Seleccionar]
class ClaseA
{
public:
  void funcion () {};

};

class ClaseB : public ClaseA
{
  void funcion () {};
};

int main ()
{
  ClaseB *objeto = new ClaseB; //Hemos sobrecargado "funcion" asi que se llamará a la de la clase que hereda

}



Y luego también he leído ejemplos en los que hace lo siguiente:

Código (cpp) [Seleccionar]
class ClaseA
{
public:
  virtual void funcion () {};

};

class ClaseB : public ClaseA
{
  void funcion () {};
};

int main ()
{
  ClaseB *objeto = new ClaseB;

}


Es decir, declaramos un objeto de tipo "ClaseB" y reservamos memoria también "ClaseB", sin embargo usa la función "virtual" en la clase base. ¿Por qué?, ¿para qué añadir "virtual" si sin ella automáticamente se sobrecarga la función y se llama a la de la clase que hereda (como en el ejemplo anterior)?.

Gracias y saludos.

[L]ord [R]NA

Cuando escribes virtual en un metodo de una clase, es para obligar a la clase derivada a que tenga que implementar el metodo virtual, entiendase, tener que OBLIGATORIAMENTE añadirla al cuerpo de la clase y colocarle el cuerpo del metodo.

eleon

#2
Vale, pero entonces para qué sirve declarar un objeto de tipo "ClaseA" y reservar memoria de tipo "ClaseB", es decir, para qué sirve hacer esto:

ClaseA *puntero = new ClaseB.

Saludos.

EDITO:
Cita de: [L]ord [R]NA en 29 Julio 2012, 15:24 PM
Cuando escribes virtual en un metodo de una clase, es para obligar a la clase derivada a que tenga que implementar el metodo virtual, entiendase, tener que OBLIGATORIAMENTE añadirla al cuerpo de la clase y colocarle el cuerpo del metodo.

Para nada, acabo de probarlo y puedes hacer lo siguiente perfectamente:

Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

class ClaseA
{
public:
  virtual void funcion () {cout << "Clase A";};
};

class ClaseB : public ClaseA
{

};

int main ()
{
ClaseB objeto;
objeto.funcion(); //Se llama a la función de "ClaseA"

cin;
return 0;
}


El compilador no te obliga a sobrecargar la función en la clase derivada si añades "virtual" en la clase base; cuando no encuentra la función en la clase derivada directamente usa la de la clase base.

La única utilidad que le he encontrado a "virtual" es al hacer lo siguiente: ClaseA *puntero = new ClaseB; entonces como el puntero es de tipo ClaseA no puedes leer la función de "ClaseB" si la has sobrecargado, por ello se añade virtual.

Entonces volvemos a la pregunta inicial, para qué sirve declarar un objeto de tipo "ClaseA" y reservar memoria de tipo "ClaseB", es decir, para qué sirve hacer esto:

ClaseA *puntero = new ClaseB.

Y si lo hacemos de la manera "habitual" es decir, tanto el tipo del puntero como la memoria reservada son de ClaseB, ¿para qué sirve añadir "virtual" en la clase base? si obtenemos el mismo efecto si no lo usamos (y eso es algo que he visto en muchos códigos).

Saludos.