Constructors e RAII
Um destructor, escrito como o nome da class prefixado com ~, roda automaticamente quando um object sai de scope — deterministicamente, não em algum ponto posterior imprevisível como o finalizer de um coletor de lixo poderia fazer. Esse pareamento de um constructor que adquire um recurso com um destructor que o libera é 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;
}Before scope Logger created Inside scope Logger destroyed After scope
Note a ordem exata: o destructor roda no instante em que log sai do seu bloco envolvente, antes mesmo de 'After scope' ser impresso. Essa é a ideia central por trás de todo tipo que gerencia recursos em C++ — file handles, locks, e os smart pointers abordados mais adiante neste curso todos se apoiam exatamente nesse mecanismo, em vez do timing indeterminado de um coletor de lixo.
A seguir: encapsulation — controle de acesso, e por que tornar fields private importa quando uma class tem invariantes a proteger.
Practice exercise
Defina uma class Counter cujo constructor imprima "Counter started" e cujo destructor imprima "Counter finished". Crie um Counter em main, imprima "Running" depois de criá-lo, depois deixe-o sair de scope.