Funciones virtuales en C++

junio 17, 2013

En la programación orientada a objetos nos encontramos con el concepto de polimorfismo. No es otra cosa que la capacidad para que diferentes clases derivadas de una misma superclase, utilicen una misma función de forma diferente.

El polimorfismo en C++ se implementa con la ayuda de la funciones virtuales.

Nada mejor que ilustrarlo con un ejemplo.

Tenemos dos clases:

1
2
3
4
5
6
7
8
9
10
11
class Animal
{
    public:
        void eat() { std::cout << "Estoy comiendo comida genérica"; }
}
 
class Cat : public Animal
{
    public:
        void eat() { std::cout << "Estoy comiendo comida de gato"; }
}

En la función main tenemos:

1
2
3
4
5
Animal *animal = new Animal;
Cat *cat = new Cat;
 
animal->eat(); // Imprime: "Estoy comiendo comida genérica"
cat->eat();    // Imprime: "Estoy comiendo comida de gato"

Perfecto, en este caso no necesitamos funciones virtuales y todo funciona como esperamos.

Pero si por cualquier motivo necesitamos llamar a la función eat() desde una función intermedia:

1
2
// Podemos poner esta función al principio de nuestro archivo main.cpp
void oneFunction(Animal *animal) { animal->eat(); }

Modificamos nuestra función main:

1
2
3
4
5
Animal *animal = new Animal;
Cat *cat = new Cat;
 
oneFunction(animal) // Imprime: "Estoy comiendo comida genérica"
oneFunction(cat)    // Imprime: "Estoy comiendo comida genérica"

Como podemos comprobar, en este caso siempre se llama a la función eat() de la superclase y no a la de la clase hija (Cat).

La solución es convertir la función eat() en una función virtual:

1
2
3
4
5
class Animal
{
    public:
        virtual void eat() { std::cout << "Estoy comiendo comida genérica"; }
}

En el main:

1
2
oneFunction(animal) // Imprime: "Estoy comiendo comida genérica"
oneFunction(cat)    // Imprime: "Estoy comiendo comida de gato"

Aunque no es necesario, a mi me gusta indicar que una función es virtual también en la clase hija. Así, si nos encontramos con una clase de otro programador que hereda de una superclase, sabremos de un solo vistazo cuales son las funciones sobreescritas (override).

Por tanto, nuestra clase Cat quedaría así:

1
2
3
4
5
class Cat : public Animal
{
    public:
        virtual void eat() { std::cout << "Estoy comiendo comida de gato"; }
}
CompartirTweet about this on TwitterShare on TumblrShare on FacebookShare on LinkedInShare on Google+Email this to someone

Tags ; , , ,

1 comentario

    Sergi Granell Jun 17, 2013

    Buen artículo!

    Responder

Escribe un comentario

Los comentarios son moderados y se utiliza rel="nofollow" para los enlaces.