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

Funciones virtuales de C++

Funciones virtuales de C++

En este tutorial, aprenderemos sobre la función virtual de C++ y su uso con la ayuda de ejemplos.

Una función virtual es una función miembro en la clase base que esperamos redefinir en clases derivadas.

Básicamente, se usa una función virtual en la clase base para garantizar que la función sea anulada . Esto se aplica especialmente a los casos en los que un puntero de la clase base apunta a un objeto de una clase derivada.

Por ejemplo, considere el siguiente código:

class Base {
   public:
    void print() {
        // code
    }
};

class Derived : public Base {
   public:
    void print() {
        // code
    }
};

Más tarde, si creamos un puntero de Base escribe para apuntar a un objeto de Derived class y llama al print() función, llama al print() función del Base clase.

En otras palabras, la función miembro de Base no se anula.

int main() {
    Derived derived1;
    Base* base1 = &derived1;

    // calls function of Base class
    base1->print();

    return 0;
}

Para evitar esto, declaramos el print() función del Base clase como virtual usando el virtual palabra clave.

class Base {
   public:
    virtual void print() {
        // code
    }
};

Las funciones virtuales son una parte integral del polimorfismo en C++. Para obtener más información, consulta nuestro tutorial sobre el polimorfismo de C++.


Ejemplo 1:Función virtual C++

#include <iostream>
using namespace std;

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

class Derived : public Base {
   public:
    void print() {
        cout << "Derived Function" << endl;
    }
};

int main() {
    Derived derived1;

    // pointer of Base type that points to derived1
    Base* base1 = &derived1;

    // calls member function of Derived class
    base1->print();

    return 0;
}

Salida

Derived Function

Aquí, hemos declarado el print() función de Base como virtual .

Entonces, esta función se anula incluso cuando usamos un puntero de Base tipo que apunta al Derived objeto derivado1 .


Identificador de anulación de C++

C++ 11 nos ha dado un nuevo identificador override eso es muy útil para evitar errores al usar funciones virtuales.

Este identificador especifica las funciones miembro de las clases derivadas que anulan la función miembro de la clase base.

Por ejemplo,

class Base {
   public:
    virtual void print() {
        // code
    }
};

class Derived : public Base {
   public:
    void print() override {
        // code
    }
};

Si usamos un prototipo de función en Derived class y definimos esa función fuera de la clase, luego usamos el siguiente código:

class Derived : public Base {
   public:
    // function prototype
    void print() override;
};

// function definition
void Derived::print() {
    // code
}

Uso de anulación de C++

Al usar funciones virtuales, es posible cometer errores al declarar las funciones miembro de las clases derivadas.

Usando el override El identificador solicita al compilador que muestre mensajes de error cuando se cometen estos errores.

De lo contrario, el programa simplemente compilará pero la función virtual no se anulará.

Algunos de estos posibles errores son:


Uso de funciones virtuales de C++

Supongamos que tenemos una clase base Animal y clases derivadas Dog y Cat .

Supongamos que cada clase tiene un miembro de datos llamado tipo . Supongamos que estas variables se inicializan a través de sus respectivos constructores.

class Animal {
   private:
    string type;
    ... .. ...
    public:
      Animal(): type("Animal") {}
    ... .. ...
};

class Dog : public Animal {
   private:
    string type;
    ... .. ...
    public:
      Animal(): type("Dog") {}
    ... .. ...
};

class Cat : public Animal {
   private:
    string type;
      ... .. ...
    public:
      Animal(): type("Cat") {}
    ... .. ...
};

Ahora, supongamos que nuestro programa requiere que creemos dos public funciones para cada clase:

  1. getType() para devolver el valor de tipo
  2. print() para imprimir el valor de type

Podríamos crear ambas funciones en cada clase por separado y anularlas, lo que sería largo y tedioso.

O podríamos hacer getType() virtuales en el Animal clase, luego cree un único print() separado función que acepta un puntero de Animal tipo como su argumento. Entonces podemos usar esta única función para anular la función virtual.

class Animal {
    ... .. ...
   public:
    ... .. ...
    virtual string getType {...}
};

... .. ...
... .. ...

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

Esto hará que el código sea más corto , limpiador y menos repetitivo .


Ejemplo 2:Demostración de función virtual de C++

// C++ program to demonstrate the use of virtual function

#include <iostream>
#include <string>
using namespace std;

class Animal {
   private:
    string type;

   public:
    // constructor to initialize type
    Animal() : type("Animal") {}

    // declare virtual function
    virtual string getType() {
        return type;
    }
};

class Dog : public Animal {
   private:
    string type;

   public:
    // constructor to initialize type
    Dog() : type("Dog") {}

    string getType() override {
        return type;
    }
};

class Cat : public Animal {
   private:
    string type;

   public:
    // constructor to initialize type
    Cat() : type("Cat") {}

    string getType() override {
        return type;
    }
};

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

int main() {
    Animal* animal1 = new Animal();
    Animal* dog1 = new Dog();
    Animal* cat1 = new Cat();

    print(animal1);
    print(dog1);
    print(cat1);

    return 0;
}

Salida

Animal: Animal
Animal: Dog
Animal: Cat

Aquí, hemos usado la función virtual getType() y un Animal puntero ani para evitar repetir el print() funcionan en todas las clases.

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

En main() , hemos creado 3 Animal punteros para crear dinámicamente objetos de Animal , Dog y Cat clases.

// dynamically create objects using Animal pointers
Animal* animal1 = new Animal();
Animal* dog1 = new Dog();
Animal* cat1 = new Cat();

Luego llamamos al print() función usando estos punteros:

  1. Cuando print(animal1) se llama, el puntero apunta a un Animal objeto. Entonces, la función virtual en Animal la clase se ejecuta dentro de print() .
  2. Cuando print(dog1) se llama, el puntero apunta a un Dog objeto. Entonces, la función virtual se anula y la función de Dog se ejecuta dentro de print() .
  3. Cuando print(cat1) se llama, el puntero apunta a un Cat objeto. Entonces, la función virtual se anula y la función de Cat se ejecuta dentro de print() .

Lenguaje C

  1. Pasar matriz a una función en programación C++
  2. Clases y objetos de C++
  3. Función amiga de C++ y Clases amigas
  4. Plantillas de clase de C++
  5. Funciones de C++ con ejemplos de programas
  6. Funciones de Verilog
  7. C - Funciones
  8. Clases de almacenamiento en C++
  9. Sobrecarga de C++ (operador y función)
  10. Polimorfismo en C++
  11. Abstracción de datos en C++