AnyCompiler

Constructors y RAII

Un destructor, escrito como el nombre de la class con ~ como prefijo, se ejecuta automáticamente cuando un object sale de scope — de forma determinista, no en algún punto posterior impredecible como podría hacerlo el finalizer de un recolector de basura. Este emparejamiento de un constructor que adquiere un recurso con un destructor que lo libera es RAII: Resource Acquisition Is Initialization.

#include <iostream>
using namespace std;

class Logger {
public:
    Logger() {
        cout << "Logger created" << endl;
    }
    ~Logger() {
        cout << "Logger destroyed" << endl;
    }
};

int main() {
    cout << "Before scope" << endl;
    {
        Logger log;
        cout << "Inside scope" << endl;
    }
    cout << "After scope" << endl;
    return 0;
}
Output
Before scope
Logger created
Inside scope
Logger destroyed
After scope

Fíjate en el orden exacto: el destructor se ejecuta en el instante en que log sale de su bloque contenedor, incluso antes de que se imprima 'After scope'. Esta es la idea central detrás de todo tipo que gestiona recursos en C++ — los file handles, locks, y los smart pointers cubiertos más adelante en este curso se apoyan exactamente en este mecanismo, en vez de en el momento indeterminado de un recolector de basura.

Siguiente: encapsulation — control de acceso, y por qué hacer private los fields importa una vez que una class tiene invariantes que proteger.

Practice exercise

Define una class Counter cuyo constructor imprima "Counter started" y cuyo destructor imprima "Counter finished". Crea un Counter en main, imprime "Running" después de crearlo, luego déjalo salir de scope.