Destructor virtual puro en C++

Un destructor virtual puro se puede declarar en C++. Después de que se haya creado un destructor como un objeto virtual puro (instancia de una clase), donde se proporciona el cuerpo del destructor. Esto se debe al hecho de que los destructores no se anularán en las clases derivadas, sino que se llamarán en orden inverso. Como resultado, para un destructor virtual puro, debe especificar un cuerpo de destructor .

Cuando se destruyen instancias de una clase derivada mediante un objeto de puntero de clase base, se utiliza un destructor virtual para liberar espacio de memoria asignado por la instancia o el objeto de la clase derivada. 

Nota: Solo los Destructores pueden ser virtuales. Los constructores no se pueden declarar como virtuales, esto se debe a que si intenta anular un constructor declarándolo en una clase base/superclase y llamarlo en la clase derivada/subclase con las mismas funcionalidades, siempre dará un error ya que anular significa una característica que nos permite usar un método de la clase principal en la clase secundaria que no es posible. 

¿Puede un destructor ser puramente virtual en C++?  
Sí, es posible tener un destructor virtual puro . Los destructores virtuales puros son legales en C++ estándar y una de las cosas más importantes para recordar es que si una clase contiene un destructor virtual puro, debe proporcionar un cuerpo de función para el destructor virtual puro. 

¿Por qué una función virtual pura requiere un cuerpo de función?

La razón es que los destructores (a diferencia de otras funciones) en realidad no se ‘anulan’, sino que siempre se les llama en el orden inverso a la derivación de la clase. Esto significa que primero se invocará un destructor de clases derivadas, luego se llamará al destructor de clases base. Si no se proporciona la definición del destructor virtual puro, ¿a qué cuerpo de función se llamará durante la destrucción del objeto? Por lo tanto, el compilador y el enlazador imponen la existencia de un cuerpo de función para destructores virtuales puros. 
 
Ejemplo:

CPP

// C++ Program to demonstrate a pure virtual destructor
#include <iostream>
using namespace std;
 
// Initialization of base class
class Base {
public:
    virtual ~Base() = 0;
    // Pure virtual destructor
};
 
// Initialization of derived class
class Derived : public Base {
public:
    ~Derived() { cout << "~Derived() is executed"; }
};
 
// Driver Code
int main()
{
    // base class pointer which is
    // allocating fresh storage
    // for Derived function object's
    Base* b = new Derived();
    delete b;
    return 0;
}

El enlazador producirá el siguiente error en el programa anterior. 

test.cpp:(.text$_ZN7DerivedD1Ev[__ZN7DerivedD1Ev]+0x4c): 
undefined reference to `Base::~Base()'  error: ld returned 1 exit status

Ahora bien, si se proporciona la definición para el destructor virtual puro, entonces el programa compila y funciona bien.

CPP

// C++ program to demonstrate if the value of
// of pure virtual destructor are provided
// then the program compiles & runs fine.
 
#include <iostream>
 
// Initialization of base class
class Base {
public:
    virtual ~Base() = 0; // Pure virtual destructor
};
Base::~Base() // Explicit destructor call
{
    std::cout << "Pure virtual destructor is called";
}
 
// Initialization of derived class
class Derived : public Base {
public:
    ~Derived() { std::cout << "~Derived() is executed\n"; }
};
 
int main()
{
    // Calling of derived member function
    Base* b = new Derived();
    delete b;
    return 0;
}
Producción

~Derived() is executed
Pure virtual destructor is called

¿Cómo funcionó MÁGICAMENTE el código anterior?

Básicamente, esto funciona porque los destructores se llamarán recursivamente de abajo hacia arriba si y solo si el valor se pasa en el destructor virtual. Entonces, vtable es una tabla que contiene punteros de todas las funciones virtuales que define la clase, y el compilador proporciona vptr a la clase como un ‘ puntero oculto ‘ que apunta a la vtable ideal, por lo que el compilador utiliza un índice preciso o correcto, calculado en tiempo de compilación, a la vtable que enviará la función virtual correcta en tiempo de ejecución.

Es importante tener en cuenta que una clase se convierte en una clase abstracta (al menos una función que no tiene definición) cuando contiene un destructor virtual puro.

Ejemplo:

CPP

// C++ program to demonstrate how a class becomes
// an abstract class when a pure virtual destructor is
// passed
 
#include <iostream>
class Test {
public:
    virtual ~Test() = 0;
    // Test now becomes abstract class
};
Test::~Test() {}
 
// Driver Code
int main()
{
    Test p;
    Test* t1 = new Test;
    return 0;
}

El programa anterior falla en una compilación y muestra los siguientes mensajes de error. 

[Error] cannot declare variable 'p' to be of abstract type 'Test' 
[Note] because the following virtual functions are pure within 'Test': 
[Note] virtual Test::~Test() 
[Error] cannot allocate an object of abstract type 'Test' 
[Note] since type 'Test' has pure virtual functions

Este artículo fue aportado por Meet Pravasi . 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 *