<p dir="ltr">Ótimo Leandro, valeu.</p>
<p dir="ltr">Agora só fica a dúvida como usar classe que extendem de.</p>
<p dir="ltr">class A {}<br>
class B : public B {}</p>
<p dir="ltr">A ob_a = new B;</p>
<p dir="ltr">Como ficaria isso no auto, sem new?<br>
</p>
<div class="gmail_quote">Em 23 de fev de 2016 4:44 PM, "Leandro A. F. Pereira" <<a href="mailto:leandro@tia.mat.br">leandro@tia.mat.br</a>> escreveu:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><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> Leandro</div>
</div></div>
<br>_______________________________________________<br>
Lista do LHC <<a href="http://lhc.net.br" rel="noreferrer" target="_blank">http://lhc.net.br</a>><br>
<a href="mailto:HSC@listas.tia.mat.br">HSC@listas.tia.mat.br</a><br>
<a href="http://listas.tia.mat.br/listinfo.cgi/hsc-tia.mat.br" rel="noreferrer" target="_blank">http://listas.tia.mat.br/listinfo.cgi/hsc-tia.mat.br</a><br>
<br></blockquote></div>