Por que é errado usar std :: auto_ptr <> com contentores normais?
Pergunta
Por que é errado usar std::auto_ptr<>
com contêineres padrão?
Solução
O padrão C ++ diz que um elemento STL deve ser "copy-constructible" e "transferível". Em outras palavras, um elemento deve ser capaz de ser atribuído ou copiado e os dois elementos são logicamente independentes. std::auto_ptr
não cumprir este requisito.
Tome por exemplo este código:
class X
{
};
std::vector<std::auto_ptr<X> > vecX;
vecX.push_back(new X);
std::auto_ptr<X> pX = vecX[0]; // vecX[0] is assigned NULL.
Para superar essa limitação, você deve usar o std::unique_ptr
, < a href = "http://msdn.microsoft.com/en-us/library/bb982026.aspx" rel = "noreferrer"> std::shared_ptr
ou std::weak_ptr
ponteiros inteligentes ou o impulso equivalentes, se você não tem C ++ 11. Aqui está a documentação impulso biblioteca para esses ponteiros inteligentes.
Outras dicas
O copiar semântica de auto_ptr
não são compatíveis com os recipientes.
Especificamente, copiando um auto_ptr
para outro não cria dois objetos iguais desde o primeiro perdeu sua propriedade do ponteiro.
Mais especificamente, a cópia de um auto_ptr
faz com que uma das cópias para deixar de ir ao ponteiro. Qual destes restos no recipiente não está definido. Portanto, você pode acessar aleatoriamente perder a ponteiros se você armazenar auto_ptrs
nos recipientes.
Dois Super excelentes artigos sobre o assunto:
Os contêineres STL precisa ser capaz de copiar os itens armazenados neles, e são projetados para esperar o original ea cópia seja equivalente. objetos ponteiro auto ter um contrato completamente diferente, em que a cópia cria uma transferência de propriedade. Isto significa que os recipientes de auto_ptr vai exibem comportamento estranho, dependendo do uso.
Há uma descrição detalhada do que pode dar errado em STL efetiva (Scott Meyers) o item 8 e também uma descrição não tão detalhada em Effective C ++ (Scott Meyers) item 13.
contêineres STL armazenar cópias de itens contidos. Quando um auto_ptr é copiado, ele define o velho ptr como nulo. Muitos métodos de contêineres são quebradas por este comportamento.
C ++ 03 Norma (ISO-IEC 14882-2003) diz na cláusula 20.4.5 parágrafo 3:
[...] [ Nota: [...] O auto_ptr não atender aos requisitos CopyConstructible e atribuíveis para Biblioteca Padrão elementos de contêiner e instanciar assim um recipiente Biblioteca Padrão com um auto_ptr resulta em comportamento indefinido. - nota final ]
C ++ 11 Norma (ISO-IEC 14882-2011) diz no apêndice parágrafo D.10.1 3:
[...] Nota: [...] instâncias de auto_ptr atender os requisitos da MoveConstructible e MoveAssignable, mas não cumprem os requisitos de CopyConstructible e CopyAssignable. - nota final]
C ++ 14 Norma (ISO-IEC 14882-2014) diz no apêndice C.4.2 Anexo D: compatibilidade características:
Alterar : O modelos de classe auto_ptr, unary_function e binary_function, os modelos de função random_shuffle, eo modelos de função (e seus tipos de retorno) ptr_fun, mem_fun, mem_fun_ref, bind1st e bind2nd não estão definidos.
Justificação :. Substituído por novos recursos
Efeito sobre características originais : Válido C ++ 2014 o código que usa esses modelos de classe e modelos de função pode falhar para compilar neste Norma Internacional.