Funciones virtuales puras y clases abstractas en C++

A veces, la implementación de todas las funciones no se puede proporcionar en una clase base porque no conocemos la implementación. Tal clase se llama clase abstracta. Por ejemplo, sea Shape una clase base. No podemos proporcionar la implementación de la función dibujar() en Shape, pero sabemos que cada clase derivada debe tener una implementación de dibujar(). De manera similar, una clase Animal no tiene implementación de move() (suponiendo que todos los animales se muevan), pero todos los animales deben saber cómo moverse. No podemos crear objetos de clases abstractas.
Una función virtual pura (o función abstracta) en C++ es una función virtualpara lo cual podemos tener implementación, pero debemos anular esa función en la clase derivada, de lo contrario, la clase derivada también se convertirá en una clase abstracta (para obtener más información sobre dónde proporcionamos implementación para tales funciones, consulte este https://stackoverflow.com/ question/2089083/pure-virtual-function-with-implementation ). Una función virtual pura se declara asignando 0 en la declaración. Vea el siguiente ejemplo. 

CPP

// An abstract class
class Test
{  
    // Data members of class
public:
    // Pure Virtual Function
    virtual void show() = 0;
   
   /* Other members */
};

Un ejemplo completo: 
una función virtual pura se implementa mediante clases que se derivan de una clase abstracta. El siguiente es un ejemplo simple para demostrar lo mismo.

CPP

#include<iostream>
using namespace std;
 
class Base
{
   int x;
public:
    virtual void fun() = 0;
    int getX() { return x; }
};
 
// This class inherits from Base and implements fun()
class Derived: public Base
{
    int y;
public:
    void fun() { cout << "fun() called"; }
};
 
int main(void)
{
    Derived d;
    d.fun();
    return 0;
}

Producción: 

fun() called

Algunos datos interesantes:  
1) Una clase es abstracta si tiene al menos una función virtual pura.  
En el siguiente ejemplo, Test es una clase abstracta porque tiene una función virtual pura show(). 

C++

 

Producción: 

Compiler Error: cannot declare variable 't' to be of abstract
 type 'Test' because the following virtual functions are pure 
within 'Test': note:     virtual void Test::show() 

2) Podemos tener punteros y referencias de tipo de clase abstracta.  
Por ejemplo, el siguiente programa funciona bien. 

CPP

#include<iostream>
using namespace std;
 
class Base
{
public:
    virtual void show() = 0;
};
 
class Derived: public Base
{
public:
    void show() { cout << "In Derived \n"; }
};
 
int main(void)
{
    Base *bp = new Derived();
    bp->show();
    return 0;
}

Producción: 

In Derived 

3) Si no anulamos la función virtual pura en la clase derivada, la clase derivada también se convierte en una clase abstracta.  
El siguiente ejemplo demuestra lo mismo.  

CPP

#include<iostream>
using namespace std;
class Base
{
public:
    virtual void show() = 0;
};
 
class Derived : public Base { };
 
int main(void)
{
  Derived d;
  return 0;
}
Compiler Error: cannot declare variable 'd' to be of abstract type 
'Derived'  because the following virtual functions are pure within
'Derived': virtual void Base::show() 

4) Una clase abstracta puede tener constructores.  
Por ejemplo, el siguiente programa compila y funciona bien. 

CPP

#include<iostream>
using namespace std;
 
// An abstract class with constructor
class Base
{
protected:
int x;
public:
virtual void fun() = 0;
Base(int i) {
              x = i;
            cout<<"Constructor of base called\n";
            }
};
 
class Derived: public Base
{
    int y;
public:
    Derived(int i, int j):Base(i) { y = j; }
    void fun() { cout << "x = " << x << ", y = " << y<<'\n'; }
};
 
int main(void)
{
    Derived d(4, 5);
    d.fun();
   
  //object creation using pointer of base class
    Base *ptr=new Derived(6,7);
      ptr->fun();
    return 0;
}

Producción: 

Constructor of base called
x = 4, y = 5
Constructor of base called
x = 6, y = 7

5) También se puede definir una clase abstracta en C++ usando la palabra clave struct .

P.ej :

estructura formaclase

{

sorteo vacío virtual() = 0;

}

Comparación con Java 
En Java, una clase se puede hacer abstracta usando la palabra clave abstract. De manera similar, una función puede hacerse puramente virtual o abstracta usando la palabra clave abstracta. Consulte 
Clases abstractas en Java para obtener más detalles.
Interfaz vs clases abstractas: 
una interfaz no tiene implementación de ninguno de sus métodos, puede considerarse como una colección de declaraciones de métodos. En C++, se puede simular una interfaz haciendo que todos los métodos sean puramente virtuales. En Java, hay una palabra clave separada para interfaz. 

Podemos pensar en la interfaz como archivos de encabezado en C++, como en los archivos de encabezado, solo proporcionamos el cuerpo de la clase que lo implementará. De manera similar, en Java en la interfaz, solo proporcionamos el cuerpo de la clase y escribimos el código real en cualquier clase que lo implemente.
Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *