Función virtual


Función virtual

En programación orientada a objetos (POO), una función virtual o método virtual es una función cuyo comportamiento, al ser declarado "virtual", es determinado por la definición de una función con la misma cabecera en alguna de sus subclases. Este concepto es una parte muy importante del polimorfismo en la POO.

El concepto de función virtual soluciona los siguientes problemas:

En POO, cuando una clase derivada hereda de una clase base, un objeto de la clase derivada puede ser referido (o coercionado) tanto como del tipo de la clase base como del tipo de la clase derivada. Si hay funciones de la clase base redefinidas por la clase derivada, aparece un problema cuando un objeto derivado ha sido cohercionado como del tipo de la clase base. Cuando un objeto derivado es referido como del tipo de la base, el comportamiento de la llamada a la función deseado es ambiguo.

Distinguir entre virtual y no virtual sirve para resolver este problema. Si la función en cuestión es designada "virtual", se llamará a la función de la clase derivada (si existe). Si no es virtual, se llamará a la función de la clase base.

Contenido

Ejemplo

Por ejemplo, una clase base Animal podría tener una función virtual come. La subclase Pez implementaría come() de forma diferente que la subclase Lobo, pero se podría invocar a come() en cualquier instancia de una clase referida como Animal, y obtener el comportamiento de come() de la subclase específica.

Esto permitiría a un programador procesar una lista de objetos de la clase Animal, diciendo a cada uno que coma (llamando a come()), sin saber qué tipo de animales hay en la lista. Tampoco tendría que saber cómo come cada animal, o cuántos tipos de animales puede llegar a existir.

El siguiente, es un ejemplo en C++:

# include <iostream>
class Animal
{
public:
    virtual void come() { std::cout << "Yo como como un animal genérico.\n"; }
    virtual ~Animal() {}
};
 
class Lobo : public Animal
{
public:
    void come() { std::cout << "¡Yo como como un lobo!\n"; }
    virtual ~Lobo() {}
};
 
class Pez : public Animal
{
public:
    void come() { std::cout << "¡Yo como como un pez!\n"; }
    virtual ~Pez() {}
};
 
class OtroAnimal : public Animal
{
    virtual ~OtroAnimal() {}
};
 
int main()
{
    Animal *unAnimal[4];
    unAnimal[0] = new Animal();
    unAnimal[1] = new Lobo();
    unAnimal[2] = new Pez();
    unAnimal[3] = new OtroAnimal();
 
    for(int i = 0; i < 4; i++) {
        unAnimal[i]->come();
    }
 
    for (int i = 0; i < 4; i++) {
        delete unAnimal[i];
    }
    return 0;
}

Salida con el método virtual come:

Yo como como un animal genérico.
¡Yo como como un lobo!
¡Yo como como un pez!
Yo como como un animal genérico.

Salida sin el método virtual come:

Yo como como un animal genérico.
Yo como como un animal genérico.
Yo como como un animal genérico.
Yo como como un animal genérico.

Las Clases abstractas y funciones virtuales puras

Una función virtual pura o método virtual puro es una función virtual que necesita ser implementada por una clase derivada que no sea abstracta. Las clases que contienen métodos virtuales puros son denominadas "abstractas". Éstas no pueden ser instanciadas directamente, y una subclase de una clase abstracta sólo puede ser instanciada directamente si todos los métodos virtuales puros han sido implementados por esa clase o una clase padre.

Los métodos virtuales puros normalmente tienen una declaración (cabecera) pero no tienen definición (implementación). Como ejemplo, una clase base abstracta como "SimboloMatematico" puede ofrecer una función virtual pura como hazOperacion, y las clases derivadas "Suma" y "Resta" pueden implementar hazOperacion para ofercer implementaciones concretas. La implementación de hazOperacion no tendría sentido en la clase "SimboloMatematico" porque "SimboloMatematico" es un concepto abstracto cuyo comportamiento es definido solamente por cada tipo (subclase) de "SimboloMatematico" dado.

De forma similar, una subclase dada de "SimboloMatematico" no sería completa sin una implementación de hazOperacion. Aunque los métodos virtuales puros normalmente no tienen implementación en la clase que los declara, en C++ permite hacer esto, ofreciendo un comportamiento por omisión en el que la clase derivada puede delegar si es apropiado.

Las funciones virtuales puras también son utilizadas donde las declaraciones de métodos se utilizan para definir una interfaz para la que las clases derivadas proveerán todas las implementaciones. Una clase abstracta sirviendo como interfaz contiene sólo funciones virtuales puras, y ningún miembro de datos (variables, constantes, etc.) ni métodos ordinarios. El uso de clases puramente abstractas como interfaces funciona en C++ ya que éste soporta herencia múltiple. Debido a que muchos lenguajes orientados a objetos no soportan herencia múltiple, normalmente ofrecen un mecanismo por separado para hacer interfaces. Esto es así por ejemplo en Java.

C++

En C++, las funciones virtuales puras son declaradas utilizando una sintaxis especial = 0 como se muestra a continuación:

 class B {
   virtual void una_funcion_virtual_pura() = 0;
 };

La declaración de la función virtual pura ofrece sólo la declaración del método. Normalmente no se ofrece una implementación de la función virtual pura en una clase abstracta, pero puede ofrecerse siempre que no sea en la declaración de la clase abstracta (no debe ser definida "inline"). Toda clase hija no-abstracta continúa necesitando redefinir el método, pero la implementación (definición) ofrecida por la clase abstracta puede ser llamada de esta forma:

void Abstracta::virtual_pura() {
  // haz algo
}
 
class Hija : Abstracta {
  virtual void virtual_pura(); // ya no es abstracta; puede ser instanciada
};
 
void Hija::virtual_pura() {
  Abstracta::virtual_pura(); // se ejecuta la implementación de la clase abstracta
}

El compilador sabe a qué implementación del método llamar en tiempo de ejecución creando una tabla de punteros a todas las funciones virtuales de una clase, llamada vtable o tabla virtual.

Destructores virtuales

Los lenguajes orientados a objetos normalmente gestionan la reserva y la liberación de memoria automáticamente cuando los objetos son creados y destruidos. Sin embargo, algunos lenguajes orientados a objetos permiten implementar un método destructor personalizado si se desea. Uno de estos lenguajes es C++, y como se ilustra en el siguiente ejemplo, es importante para una clase base de C++ tener un destructor virtual para asegurar que se llamará siempre al destructor de la clases derivadas inferior. En el ejemplo siguiente, sin destructor virtual, al eliminar (delete) una instancia de la clase B, se llamará correctamente al destructor de la clase B y al de la clase A si se elimina como instancia de B; una instancia de B, eliminada mediante un puntero a su clase base A, fallará al no llamar al destructor de B.

# include <iostream>
 
class A
{
public:
 
   A() { }
   ~A() { std::cout << "Destruye A" << std::endl; }
};
 
class B : public A
{
public:
 
  B() { }
  ~B() { std::cout << "Destruye B" << std::endl; }
};
 
int main()
{
  A* b1 = new B;
  B* b2 = new B;
 
  delete b1; // Sólo se llama a ~A() aunque b1 sea una instancia de la clase B
             // porque ~A() no se ha declarado como virtual
  delete b2; // Llama a los destructores ~B() y ~A()
 
  return 0;
}

Salida:

Destruye A
Destruye B
Destruye A

La declaración correcta del destructor para la clase A como virtual ~A() asegurará que el destructor para la clase B sea llamado en ambos casos del ejemplo anterior.

Véase también

Referencias

  • C++ FAQ Lite Copyright © 1991-2006, Marshall Cline. (en inglés)

Wikimedia foundation. 2010.

Mira otros diccionarios:

  • Virtual — y virtualidad, lo opuesto a lo real y a la realidad, pueden referirse a: Partícula virtual Temperatura virtual Realidad virtual Mundos virtuales Imagen virtual Función virtual Sexo virtual Mascota virtual Bien virtual Herencia virtual… …   Wikipedia Español

  • Virtual PC — Programa desarrollado por Connectix y comprado por Microsoft para crear ordenadores virtuales. Es decir, su función es emular un hardware sobre el que funcionen varios sistemas operativos, con esto se puede conseguir ejecutar varios sistemas… …   Enciclopedia Universal

  • Windows Virtual PC — Desarrollador Microsoft Corporation Windows Virtual PC: página principal Información general Última versión estable …   Wikipedia Español

  • Memoria virtual — Cómo la memoria virtual se mapea a la memoria física. La memoria virtual es una técnica de administración de la memoria real que permite al sistema operativo brindarle al software de usuario y a sí mismo un espacio de direcciones mayor que la… …   Wikipedia Español

  • Comunidad virtual — Se denomina comunidad virtual a aquella comunidad cuyos vínculos, interacciones y relaciones tienen lugar no en un espacio físico sino en un espacio virtual como Internet. Contenido 1 Historia 2 BBS vs Internet 3 Definición …   Wikipedia Español

  • Máquina virtual Java — Una Máquina virtual Java (en inglés Java Virtual Machine, JVM) es un máquina virtual de proceso nativo, es decir, ejecutable en una plataforma específica, capaz de interpretar y ejecutar instrucciones expresadas en un código binario especial (el… …   Wikipedia Español

  • Biblioteca Virtual de Andalucía — Saltar a navegación, búsqueda La Biblioteca Virtual de Andalucía, conocida también por su acrónimo BVA, es una biblioteca virtual creada en 2003 por la Junta de Andalucía. Se trata de un proyecto dirigido a recuperar aquellos documentos que… …   Wikipedia Español

  • Máquina virtual Parrot — ? Información general Última versión estable 3.6.0 Pájaros del Caribe 19 de julio de 2011 Género Máquina virtual …   Wikipedia Español

  • Disco virtual — Saltar a navegación, búsqueda Un disco duro virtual es un espacio ofrecido por empresas para sus clientes como una solución al almacenamiento de datos. Emula a un disco duro de ordenador y gracias a la conexión a Internet, permite el acceso desde …   Wikipedia Español

  • Temperatura virtual — La temperatura virtual (Tv) del aire se define como la temperatura que tendría el aire seco, es decir el aire sin considerar el vapor de agua, si su presión y densidad igualasen a las del aire húmedo (el aire húmedo se define como la mezcla de… …   Wikipedia Español