A auto_ptr é uma classe parte da STL que permite guardar a referência para um objeto de qualquer tipo. Quando se cria um objeto da classe auto_ptr, passando para ela o objeto apontado, ele terá a posse do objeto apontado.
Por exemplo:
class ClasseQualquer
{
public:
int valor;
};
auto_ptr< ClasseQualquer > meuAutoPtr(
new ClasseQualquer );
O objeto criado pela instrução new ClasseQualquer será agora o objeto apontado por meuAutoPtr.
Quando a instância de meuAutoPtr for destruída, ela destrói o objeto que ela aponta. Assim, quando o escopo da variável meuAutoPtr terminar, ela automaticamente irá liberar da memória o (dar um delete no) objeto para o qual ela aponta.
A classe auto_ptr possui o método get para retornar o objeto apontado:
meuAutoPtr.get(); // irá retornar a instância de ClasseQualquer
Logo, para alterar o atributo valor:
meuAutoPtr.get()->valor = 100;
Só que auto_ptr também sobrecarrega o operador ->, fazendo com que ele também retorne o objeto apontado (sendo X uma classe qualquer a assinatura do método seria "X* operator ->() const;". Devo falar mais sobre sobrecarga de operadores em postagens futuras.). Logo, podemos usar
meuAutoPtr->valor = 100;
como se meuAutoPtr fosse o próprio objeto de ClasseQualquer.
A auto_ptr possui o método release, para liberar a memória do objeto apontado por ela:
meuAutoPtr.release(); // destroi a instância de ClasseQualquer
E o método reset, para fazer com que ela aponte para outro objeto. O método reset irá destruir o objeto apontado antes de receber o novo:
meuAutoPtr.reset( new ClasseQualquer );
Na grande maioria das vezes, não precisamos usar os métodos oferecidos por auto_ptr pois sua utilidade maior é mesmo a de poder guardar a referência para um objeto e destruí-lo automaticamente assim que seu escopo terminar.
void FuncaoExemplo()
{
// Um objeto de ClasseQualquer é
// instanciado
auto_ptr< ClasseQualquer > meuAutoPtr(
new ClasseQualquer );
// Podemos acessar o objeto criado atraves
// do objeto auto_ptr de forma praticamente
// transparente (devido ao operator ->)
meuAutoPtr->valor = 100;
cout << "O valor é: " << meuAutoPtr->valor;
// O MAIS IMPORTANTE:
// Nao e' preciso desalocar a memoria que
// foi criada e passada para o auto_ptr.
// Como o escopo da variavel meuAutoPtr
// terminou ela deleta o objeto apontado
}
Essa é uma maneira simples de criar objetos com new, sem que seja preciso usar delete (ou seja, sem que seja preciso se preocupar com a memória alocada).
Cuidados no uso de auto_ptr
Quando criamos um objeto da classe auto_ptr, ele geralmente não deve ser um ponteiro. Isso porque, sendo ponteiro, nos obrigaria a usar new e delete, o que faria perder o sentido da classe.void FuncaoExemplo2_UsoSemSentido()
{
auto_ptr< ClasseQualquer > *meuAutoPtr =
new auto_ptr< ClasseQualquer >(
new ClasseQualquer );
( *meuAutoPtr )->valor = 100;
cout << "O valor é: " <<
( *meuAutoPtr )->valor;
delete meuAutoPtr;
}
Veja que foi preciso acessar o valor do ponteiro meuAutoPtr, usando asterisco...
( *meuAutoPtr )->valor = 100;
...para não precisar acessar usando get:
meuAutoPtr->get()->valor = 100;
Outro cuidado importante que deve-se ter é o atribuir uma variável da classe auto_ptr a outra. A atribuição passa a posse do objeto para a variável receptora (do lado esquerdo). Isto porque auto_ptr admite somente um dono para um objeto:
// Cria umDono possuindo uma instancia de
// ClasseQualquer
auto_ptr< ClasseQualquer > umDono(
new ClasseQualquer );
// Faz com que novoDono seja o novo dono da
// instancia e com que umDono não seja mais
// dono de nada !!!
auto_ptr< ClasseQualquer > novoDono = umDono;
umDono->valor = 100; // ERRO !
novoDono->valor = 100; // OK
Conclusão
Podemos usar a classe auto_ptr para nos ajudar a criar instâncias de outras classes sem que precisemos nos preocupar em gerenciar a memória alocada.
Em tempo, a classe pertence à biblioteca memory e é declarada dentro do namespace std.
Nenhum comentário:
Postar um comentário