<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">2016-02-23 15:51 GMT-03:00 Alejandro Mesias <span dir="ltr"><<a href="mailto:ale.mesias@gmail.com" target="_blank">ale.mesias@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Falta agora descobrir se quando o compilador libera o objeto ele chama o destrutor ou se preciso fazer isso manualmente, capaz que manualmente.</blockquote></div><br></div><div class="gmail_extra">Se alocar na pilha, quando sair do escopo, o destrutor é chamado. É comum em C++ usar um negócio chamado RAII (resource acquisition is initialization) justamente explorando esse fato. O compilador, inclusive, garante que a ordem de chamada dos destrutores será feita em ordem reversa à dos construtores (pilha e tal).<br></div><div class="gmail_extra"><br></div><div class="gmail_extra">Por exemplo, considere que tenha uma classe:<br><br></div><div class="gmail_extra">    class File {<br></div><div class="gmail_extra">    private:<br></div><div class="gmail_extra">        FILE *f_;<br></div><div class="gmail_extra">    public:<br></div><div class="gmail_extra">        File(const char *path, const char *mode) : f_(fopen(path, mode) {}<br></div><div class="gmail_extra">        ~File() {<br></div><div class="gmail_extra">            if (f_) fclose(f_);<br></div><div class="gmail_extra">        }<br></div><div class="gmail_extra">        FILE *file() { return f_; }<br></div><div class="gmail_extra">    };<br clear="all"></div><div class="gmail_extra"><br></div><div class="gmail_extra">Se você fizer isso:<br><br></div><div class="gmail_extra">   void foo() {<br></div><div class="gmail_extra">        File arquivo_a("teste.txt", "re");<br></div><div class="gmail_extra">        File arquivo_b("teste2.txt", "re");<br></div><div class="gmail_extra"><br></div><div class="gmail_extra">        for (size_t i = 0; i < 100; i++) {<br></div><div class="gmail_extra">              File arquivo_c("teste3.txt", "re");<br></div><div class="gmail_extra">        }<br></div><div class="gmail_extra">   }<br></div><div class="gmail_extra"><br></div><div class="gmail_extra">Os arquivos "teste.txt", "teste2.txt" serão abertos, "teste3.txt" será aberto e fechado 100 vezes, o arquivo "teste2.txt" será fechado e depois "teste.txt" será fechado. Automaticamente. :)<br><br></div><div class="gmail_extra">Note que o objeto só teve seu destrutor chamado pois é uma variável "auto" (no sentido C de auto, ou seja, que é desalocada quando sai do escopo, não no sentido C++11 de auto, que é um mecanismo de inferência de tipo).<br></div><div class="gmail_extra"><br></div><div class="gmail_extra">Se o objeto tivesse sido alocado com new, isso não aconteceria. Mas, hoje em dia, não há muitos motivos para se usar new e delete; prefira usar unique_ptr:<br><br></div><div class="gmail_extra">    auto arquivo = std::make_unique<File>("teste.txt", "re");<br><br></div><div class="gmail_extra">Assim a classe é alocada com new pelo make_unique, mas assim que arquivo sair do escopo, o destrutor é chamado e a memória é liberada. Dá pra colocar isso dentro de uma classe por exemplo, ou retornar um std::unique_ptr<T> de funções e deixar o compilador tomar cuidado com o tempo de vida do teu objeto.<br><br></div><div class="gmail_extra">BTW, RAII é bem massa. Um exemplo legal é o std::lock_guard, que trava um std::mutex no construtor e destrava no destrutor, então rola algo assim:<br><br></div><div class="gmail_extra">     while (true) {<br></div><div class="gmail_extra">          std::lock_guard guard(mutex_);<br></div><div class="gmail_extra"><br>          vetor_compartilhado_.push_back(foo());<br></div><div class="gmail_extra">     }<br></div><div class="gmail_extra"><br></div><div class="gmail_extra">Assim, mesmo se o std::vector::push_back() explodir com uma exceção ou se a função for mais complexa e tiver vários pontos de saída, o destrutor do lock_guard será chamado sempre.<br></div><div class="gmail_extra"><br>-- <br><div class="gmail_signature">  Leandro</div>
</div></div>