Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Industrial programming >> Lenguaje C

Dominando las funciones virtuales en C++: conceptos, ejemplos y la palabra clave override

Funciones virtuales en C++

Este tutorial explica las funciones virtuales en C++, su propósito y uso práctico ilustrado con ejemplos de código.

Una función virtual es un miembro de la clase base que esperamos que las clases derivadas sobreescriban. Declarar una función como virtual asegura que la implementación más derivada sea invocada, incluso cuando se accede a través de un puntero o referencia a la clase base.

Cuando una clase base contiene un miembro no virtual, llamar a ese miembro a través de un puntero base siempre ejecutará la versión base, independientemente del tipo de objeto real. Considere lo siguiente:

class Base {
public:
    void imprimir() {
        // implementación base
    }
};

class Derivada : public Base {
public:
    void imprimir() {
        // implementación derivada
    }
};

En el programa siguiente, un Base* apunta a una instancia de Derivada, sin embargo imprimir() resuelve a la versión base:

int main() {
    Derivada derivada1;
    Base* base1 = &derivada1;
    base1->imprimir(); // llama a Base::imprimir()
    return 0;
}

Para lograr comportamiento polimórfico, declare la función como virtual en la clase base:

class Base {
public:
    virtual void imprimir() {
        // implementación base
    }
};

Las funciones virtuales son centrales para el polimorfismo en C++. Para una inmersión más profunda, consulte nuestra guía de Polimorfismo en C++.


Ejemplo 1: Uso básico de función virtual

#include <iostream>
using namespace std;

class Base {
public:
    virtual void imprimir() {
        cout << "Función Base" << endl;
    }
};

class Derivada : public Base {
public:
    void imprimir() override {
        cout << "Función Derivada" << endl;
    }
};

int main() {
    Derivada derivada1;
    Base* base1 = &derivada1;
    base1->imprimir(); // imprime Función Derivada
    return 0;
}

Salida

Función Derivada

Como Base::imprimir es virtual, la llamada despacha a Derivada::imprimir incluso a través de un puntero base.

Dominando las funciones virtuales en C++: conceptos, ejemplos y la palabra clave override

El identificador override en C++

Desde C++11, la palabra clave override ayuda a prevenir sobreescrituras accidentales al forzar al compilador a verificar que una función realmente sobreescribe un miembro virtual de la base.

Ejemplo:

class Base {
public:
    virtual void imprimir() {
        // implementación base
    }
};

class Derivada : public Base {
public:
    void imprimir() override {
        // implementación derivada
    }
};

Si define la función de sobreescritura fuera de la clase, use:

class Derivada : public Base {
public:
    void imprimir() override; // declaración
};

void Derivada::imprimir() {
    // implementación
}

Usando override de forma segura

Sin override, un error tipográfico o discrepancia en la firma resulta silenciosamente en una nueva función en lugar de una sobreescritura, llevando a errores sutiles. El compilador emitirá un error, haciendo el problema inmediatamente visible. Errores comunes incluyen:


Uso práctico de funciones virtuales

Considere una clase base Animal con clases derivadas Perro y Gato. Cada clase tiene un miembro tipo inicializado por su constructor.

class Animal {
private:
    string tipo;
public:
    Animal() : tipo("Animal") {}
    virtual string getTipo() const {
        return tipo;
    }
};

class Perro : public Animal {
private:
    string tipo;
public:
    Perro() : tipo("Perro") {}
    string getTipo() const override {
        return tipo;
    }
};

class Gato : public Animal {
private:
    string tipo;
public:
    Gato() : tipo("Gato") {}
    string getTipo() const override {
        return tipo;
    }
};

Con getTipo() virtual, un solo helper puede imprimir cualquier animal:

void imprimir(Animal* ani) {
    cout << "Animal: " << ani->getTipo() << endl;
}

Uso en main():

int main() {
    Animal* animal1 = new Animal();
    Animal* perro1 = new Perro();
    Animal* gato1 = new Gato();
    imprimir(animal1);
    imprimir(perro1);
    imprimir(gato1);
    delete animal1;
    delete perro1;
    delete gato1;
    return 0;
}

Salida

Animal: Animal
Animal: Perro
Animal: Gato

Al hacer getTipo() virtual, evitamos duplicar la lógica de imprimir() en cada clase derivada y aseguramos que se acceda al tipo correcto.

Lenguaje C

  1. Cómo Pasar Arrays a Funciones en C++: Guía Práctica
  2. Clases y Objetos en C++: Guía Práctica de Programación Orientada a Objetos
  3. Funciones y clases amigas en C++: dominando el control de acceso
  4. Dominando las plantillas de clase en C++: guía práctica
  5. Funciones en C++ Explicadas con Ejemplos de Código Prácticos
  6. Dominando funciones en C: Estructura, declaración y mejores prácticas
  7. Entendiendo las Clases de Almacenamiento en C++: Alcance, Vida y Uso
  8. Dominando la Sobrecarga en C++: Funciones y Operadores Explicados
  9. Entendiendo el Polimorfismo en C++: Guía Práctica
  10. Dominando la Abstracción de Datos en C++: Simplifica el Diseño con Separación Interfaz-Implementación
  11. Dominar las funciones en Verilog para diseño RTL eficiente