RAII e Gerenciamento de Recursos¶
RAII vincula a vida de um recurso a um objeto. A construção estabelece posse e a destruição libera. Aplica-se a memória, arquivos, sockets, locks e transações.
Limpeza determinística¶
Objetos automáticos são destruídos ao sair do escopo, inclusive durante o desempilhamento por exceção. Membros e bases liberam recursos em ordem inversa.
std::string first_line(std::filesystem::path const& path) {
std::ifstream input{path};
if (!input) throw std::runtime_error{"cannot open input file"};
std::string line;
if (!std::getline(input, line)) {
throw std::runtime_error{"cannot read first line"};
}
return line;
} // input closes here on every exit path
Não é necessário um caminho explícito de close(). Destrutores usados para
limpeza não devem deixar exceções escapar durante o desempilhamento.
Ferramentas de posse¶
- valores diretos e contêineres: padrão preferível;
std::unique_ptr<T>: posse dinâmica exclusiva;std::shared_ptr<T>: posse compartilhada por referência;std::weak_ptr<T>: observação sem posse e quebra de ciclos;- ponteiros/referências crus: acesso sem posse com vida clara.
Prefira std::make_unique e std::make_shared quando adequados. Posse compartilhada
tem custo atômico e não torna o objeto thread-safe.
Locks são recursos¶
std::mutex mutex;
std::vector<int> values;
void append(int value) {
std::lock_guard guard{mutex};
values.push_back(value);
}
O guard libera em toda saída. std::scoped_lock adquire vários mutexes com
mecanismo de prevenção de deadlock, mas o protocolo maior ainda exige projeto.
Handle personalizado¶
Um wrapper deve adquirir ou receber um recurso, expor operações válidas, liberar no destrutor e definir cópia/movimentação. Frequentemente é movível, não copiável.
RAII versus coleta de lixo¶
GC recupera memória inalcançável conforme política do runtime. RAII encerra posse em limites determinísticos. C++ pode usar collectors e Java pode usar wrappers de escopo; os conceitos não são excludentes.
Exercícios¶
- Encapsule um handle de arquivo C em classe RAII movível.
- Explique vazamento por ciclo de
shared_ptrsem aresta fraca. - Explique por que
lock()seguido deunlock()não é seguro sob exceções.