Sobes.tech
Junior

¿Qué sabes sobre la palabra clave virtual en C++?

sobes.tech AI

Respuesta de la IA

virtual en C++ se utiliza para declarar funciones virtuales en la clase base. Esto permite implementar el polimorfismo en tiempo de ejecución (polimorfismo en tiempo de ejecución).

Aplicación:

  • Define una función en la clase base que puede ser sobrescrita (override) en clases derivadas.
  • Cuando se llama a una función virtual a través de un puntero o referencia a la clase base, en realidad se llama a la implementación de la función en el objeto de la clase derivada (si ha sido sobrescrita). Esto sucede en tiempo de ejecución mediante la tabla de funciones virtuales (vtable).

Puntos clave:

  • Solo las funciones miembro de clase pueden ser virtuales. Las funciones globales, funciones miembro estáticas y constructores no pueden ser virtuales.
  • Los destructores pueden y a menudo deben ser virtuales para evitar fugas de memoria al eliminar objetos de clases derivadas a través de un puntero a la clase base.
  • Si una función se declara virtual en la clase base, automáticamente permanece virtual en todas las clases derivadas, incluso si no se usa explícitamente la palabra clave virtual allí (aunque se recomienda usar virtual y override en clases derivadas para mayor claridad).
  • Las funciones virtuales puras se declaran con = 0 y hacen que la clase sea abstracta. No se puede instanciar directamente esa clase.

Ejemplo:

#include <iostream>

class Base {
public:
    virtual void print() {
        std::cout << "Desde Base" << std::endl;
    }

    virtual ~Base() {
        std::cout << "Destructor de Base" << std::endl;
    }
};

class Derived : public Base {
public:
    void print() override { // Uso de override para indicar claramente la sobrescritura
        std::cout << "Desde Derived" << std::endl;
    }

    ~Derived() override { // Uso de override
        std::cout << "Destructor de Derived" << std::endl;
    }
};

int main() {
    Base* ptr = new Derived(); // Puntero a la clase base apunta a un objeto derivado

    ptr->print(); // Se llama a Derived::print() debido a la función virtual
    delete ptr;   // Se llaman los destructores de Derived y luego de Base debido al destructor virtual

    return 0;
}

Conceptos relacionados:

  • vtable (tabla de funciones virtuales): Tabla de punteros a funciones virtuales de la clase. Cada objeto con funciones virtuales contiene un puntero invisible (vptr) a la vtable de su clase.
  • vptr (puntero a vtable): Necesario para determinar qué función llamar en tiempo de ejecución.
  • = 0 (función virtual pura): Indica que la función no tiene implementación en esa clase, haciendo que la clase sea abstracta.
  • override (especificador de sobrescritura): Indica explícitamente que la función en la clase derivada sobrescribe una función virtual de la base. Ayuda al compilador a detectar errores si la firma no coincide.
  • final (especificador): Prohíbe que la función virtual sea sobrescrita en clases derivadas o que la clase sea heredada.

En resumen: virtual es el mecanismo principal para implementar el polimorfismo mediante herencia y enlace dinámico en C++.