Ouvi dizer que auto_ptr
está sendo descontinuado no C ++ 11. Qual é a razão para isto?
Também gostaria de saber a diferença entre auto_ptr
e shared_ptr
.
c++
c++11
smart-pointers
auto-ptr
Brett
fonte
fonte
Respostas:
A substituição direta
auto_ptr
(ou a coisa mais próxima de uma) éunique_ptr
. No que diz respeito ao "problema", é muito simples:auto_ptr
transfere a propriedade quando é atribuído.unique_ptr
também transfere propriedade, mas graças à codificação da semântica de movimento e à magia das referências rvalue, pode fazê-lo de maneira consideravelmente mais natural. Ele também "se ajusta" ao resto da biblioteca padrão consideravelmente melhor (embora, para ser justo, parte disso seja graças ao resto da biblioteca que muda para acomodar a semântica de movimentação em vez de sempre exigir a cópia).A mudança no nome também é (IMO) bem-vinda -
auto_ptr
não diz muito sobre o que ele tenta automatizar, ao passo queunique_ptr
é uma descrição bastante razoável (embora concisa) do que é fornecido.fonte
auto_ptr
nome: auto sugere automatic como em automatic variable, e se refere a uma coisa queauto_ptr
faz: destruir o recurso gerenciado em seu destruidor (quando ele sai do escopo).auto_ptr
: open-std.org/jtc1/sc22/wg21/docs/papers/2005/…std::sort
não tem especialização paraunique_ptr
. Em vez disso, foi especificado novamente para nunca mais ser copiado. Então,auto_ptr
realmente faz o trabalho com o modernosort
. Mas o C ++ 98/03sort
é apenas um exemplo de algoritmo aqui: qualquer algoritmo genérico (fornecido por std ou escrito pelo usuário) que assume que a sintaxe de cópia tem semântica de cópia provavelmente terá um erro de tempo de execução se usado comauto_ptr
, porque se moveauto_ptr
silenciosamente com sintaxe de cópia . A questão é muito maior do que apenas .sort
Achei as respostas existentes ótimas, mas pelo ponto de vista dos ponteiros. IMO, uma resposta ideal deve ter a resposta da perspectiva do usuário / programador.
Primeira coisa (conforme apontado por Jerry Coffin em sua resposta)
shared_ptr: Se você está preocupado com a liberação de recurso / memória E se você tem mais de uma função que pode estar usando o objeto AT-DIFFERENT vezes, então vá com shared_ptr.
Por DIFFERENT-Times, pense em uma situação onde o objeto-ptr é armazenado em múltiplas estruturas de dados e posteriormente acessado. Vários threads, é claro, é outro exemplo.
unique_ptr: Se tudo que você está preocupado é liberar memória, e o acesso ao objeto é SEQUENCIAL, então vá para unique_ptr.
Por SEQUENTIAL, quero dizer, em qualquer ponto o objeto será acessado a partir de um contexto. Por exemplo, um objeto que foi criado e usado imediatamente após a criação pelo criador. Após a criação, o objeto é armazenado na estrutura de dados FIRST . Então, o objeto é destruído após UMA estrutura de dados ou é movido para a SEGUNDA estrutura de dados.
A partir desta linha, irei me referir a _ptr compartilhado / exclusivo como ponteiros inteligentes. (auto_ptr também é um ponteiro inteligente, MAS por causa de falhas em seu design, para o qual eles estão sendo descontinuados, e que acho que irei apontar nas próximas linhas, eles não devem ser agrupados com ponteiro inteligente.)
No link: http://www.cplusplus.com/reference/memory/unique_ptr/operator=/
Tipo de atribuições suportadas por unqiue_ptr
De: http://www.cplusplus.com/reference/memory/auto_ptr/operator=/
Tipo de atribuições suportadas por auto_ptr
Agora chegando ao motivo pelo qual a atribuição de cópia em si era tão desagradável, eu tenho esta teoria:
O comportamento não intencional é realmente desagradável e, portanto, não gosto do auto_ptr.
(Para 3,1415926536% dos programadores que intencionalmente desejam transferir a propriedade, o C ++ 11 deu a eles std :: move (), o que deixou sua intenção muito clara para todos os estagiários que irão ler e manter o código.)
fonte
auto_ptr
valores apontando para o mesmo objeto (já que eles não dão propriedade compartilhada, o primeiro a morrer deixará o outro com uma herança letal; isso também é válido para ounique_ptr
uso), você pode sugerir o que se pretendia em os restantes 96,8584073465% de todo o uso?*a=*b;
Aqui, apenas o valor de b é copiado para a. Espero que a propriedade de aeb ainda seja das mesmas pessoas. Você mencionou como a propriedade será transferida. Como será?auto_ptr
objeto a si mesmo. Atribuir para / de seu valor apontado não tem efeito sobre, nem relevância para, propriedade. Espero que ainda não esteja usandoauto_ptr
?shared_ptr
pode ser armazenado dentro de recipientes.auto_ptr
não posso.BTW
unique_ptr
é realmente aauto_ptr
substituição direta , ele combina as melhores características de ambosstd::auto_ptr
eboost::scoped_ptr
.fonte
Mais uma tentativa de explicar a diferença ....
Funcionalmente, o C ++ 11's
std::unique_ptr
é o "fixo"std::auto_ptr
: ambos são adequados quando - em qualquer momento durante a execução - deve haver um único proprietário de ponteiro inteligente para um objeto apontado.A diferença crucial está na construção da cópia ou atribuição de outro ponteiro inteligente que não expira, mostrado nas
=>
linhas abaixo:Acima,
ap3
silenciosamente "rouba" a propriedade de*ap
, deixandoap
definido como anullptr
, e o problema é que isso pode acontecer facilmente, sem que o programador tenha pensado em sua segurança.Por exemplo, se um
class
/struct
tem umstd::auto_ptr
membro, então fazer uma cópia de uma instância irárelease
o ponteiro da instância que está sendo copiada: isso é semântica estranha e perigosamente confusa, já que normalmente copiar algo não o modifica. É fácil para o autor da classe / estrutura ignorar a liberação do ponteiro ao raciocinar sobre invariantes e estado e, conseqüentemente, tentar cancelar a referência do ponteiro inteligente enquanto nulo, ou simplesmente não ter ainda o acesso / propriedade esperados dos dados apontados.fonte
auto_ptr não pode ser usado em contêineres STL porque tem um construtor de cópia que não atende aos requisitos do contêiner CopyConstructible . unique_ptr não implementa um construtor de cópia, portanto, os contêineres usam métodos alternativos. unique_ptr pode ser usado em contêineres e é mais rápido para algoritmos std do que shared_ptr.
fonte