C ++ 03
std::auto_ptr
- Talvez um dos originais sofria de síndrome do primeiro calado, fornecendo apenas instalações limitadas de coleta de lixo. A primeira desvantagem é que ela exige delete
destruição, tornando-os inaceitáveis para reter objetos alocados em matriz ( new[]
). Ele assume a propriedade do ponteiro, portanto, dois ponteiros automáticos não devem conter o mesmo objeto. A atribuição transferirá a propriedade e redefinirá o ponteiro automático rvalue para um ponteiro nulo. O que leva à talvez a pior desvantagem; eles não podem ser usados em contêineres STL devido à impossibilidade de ser copiada. O golpe final para qualquer caso de uso é que eles devem ser descontinuados no próximo padrão do C ++.
std::auto_ptr_ref
- Este não é um ponteiro inteligente; na verdade, é um detalhe de design usado em conjunto std::auto_ptr
para permitir a cópia e a atribuição em determinadas situações. Especificamente, ele pode ser usado para converter um não-const std::auto_ptr
em um lvalue usando o truque de Colvin-Gibbons, também conhecido como construtor de movimento, para transferir a propriedade.
Pelo contrário, talvez std::auto_ptr
não tenha sido realmente planejado para ser usado como um ponteiro inteligente de uso geral para a coleta automática de lixo. A maioria dos meus conhecimentos e suposições limitados são baseados no Uso Efetivo do auto_ptr, de Herb Sutter, e eu o uso regularmente, embora nem sempre da maneira mais otimizada.
C ++ 11
std::unique_ptr
- Este é o nosso amigo que o substituirá std::auto_ptr
, será bastante semelhante, exceto com as principais melhorias para corrigir os pontos fracos de std::auto_ptr
trabalhar com matrizes, proteção de lvalue por meio de construtor de cópia privada, ser utilizável com contêineres e algoritmos STL, etc. e a pegada de memória é limitada, este é um candidato ideal para substituir, ou talvez mais apropriadamente descrito como proprietário, de indicadores brutos. Como o "único" implica, existe apenas um proprietário do ponteiro, assim como o anteriorstd::auto_ptr
.
std::shared_ptr
- Eu acredito que isso se baseia no TR1 e boost::shared_ptr
melhorou para incluir alias e aritmética de ponteiros. Em resumo, envolve um ponteiro inteligente contado em referência em torno de um objeto alocado dinamicamente. Como o "compartilhado" implica que o ponteiro pode pertencer a mais de um ponteiro compartilhado quando a última referência do último ponteiro compartilhado fica fora do escopo, o objeto será excluído adequadamente. Eles também são seguros para threads e podem lidar com tipos incompletos na maioria dos casos. std::make_shared
pode ser usado para construir eficientemente umstd::shared_ptr
com uma alocação de heap usando o alocador padrão.
std::weak_ptr
- Igualmente baseado em TR1 e boost::weak_ptr
. Esta é uma referência a um objeto de propriedade de a std::shared_ptr
e, portanto, não impedirá a exclusão do objeto se a std::shared_ptr
contagem de referência cair para zero. Para obter acesso ao ponteiro bruto, você primeiro precisará acessar o std::shared_ptr
chamando, lock
que retornará um vazio std::shared_ptr
se o ponteiro de propriedade expirou e já foi destruído. Isso é útil principalmente para evitar contagens de referência pendentes indefinidas ao usar vários ponteiros inteligentes.
Impulso
boost::shared_ptr
- Provavelmente o mais fácil de usar nos cenários mais variados (STL, PIMPL, RAII, etc.), este é um ponteiro inteligente contado e referenciado compartilhado. Ouvi algumas queixas sobre desempenho e sobrecarga em algumas situações, mas devo tê-las ignorado porque não consigo me lembrar qual era o argumento. Aparentemente, era popular o suficiente para se tornar um objeto C ++ padrão pendente e não há inconvenientes sobre a norma em relação aos ponteiros inteligentes.
boost::weak_ptr
- Assim como a descrição anterior de std::weak_ptr
, com base nesta implementação, isso permite uma referência não proprietária a boost::shared_ptr
. Você não chama surpreendentemente lock()
para acessar o ponteiro compartilhado "forte" e deve verificar se ele é válido, pois já pode ter sido destruído. Apenas certifique-se de não armazenar o ponteiro compartilhado retornado e deixá-lo sair do escopo assim que terminar, caso contrário, você estará de volta ao problema de referência cíclica, onde suas contagens de referência serão interrompidas e os objetos não serão destruídos.
boost::scoped_ptr
- Esta é uma classe simples de ponteiro inteligente com pouca sobrecarga, provavelmente projetada para uma alternativa de melhor desempenho e boost::shared_ptr
quando utilizável. É comparável, std::auto_ptr
principalmente porque não pode ser usado com segurança como elemento de um contêiner STL ou com vários ponteiros para o mesmo objeto.
boost::intrusive_ptr
- Eu nunca usei isso, mas pelo meu entendimento ele foi projetado para ser usado ao criar suas próprias classes compatíveis com ponteiro inteligente. Você precisa implementar a referência contando você mesmo, também precisará implementar alguns métodos se quiser que sua classe seja genérica, além disso, você precisará implementar sua própria segurança de encadeamento. No lado positivo, isso provavelmente oferece a maneira mais personalizada de escolher exatamente quanto ou quão "esperteza" você deseja. intrusive_ptr
normalmente é mais eficiente do que, shared_ptr
pois permite que você tenha uma única alocação de heap por objeto. (obrigado Arvid)
boost::shared_array
- Isto é boost::shared_ptr
para matrizes. Basicamente new []
, operator[]
e, delete []
é claro, são assados. Isso pode ser usado em contêineres STL e, tanto quanto sei, tudo boost:shared_ptr
faz, embora você não possa usá boost::weak_ptr
-los. No entanto, você pode usar alternativamente um boost::shared_ptr<std::vector<>>
para funcionalidade semelhante e recuperar a capacidade de usar boost::weak_ptr
para referências.
boost::scoped_array
- Isto é boost::scoped_ptr
para matrizes. Assim como acontece com boost::shared_array
toda a variedade necessária, a matriz é incorporada. Esta é não copiável e, portanto, não pode ser usada em contêineres STL. Eu encontrei quase qualquer lugar que você queira usar isso, provavelmente você pode usar std::vector
. Eu nunca determinei o que é realmente mais rápido ou com menos sobrecarga, mas essa matriz com escopo parece muito menos envolvida que um vetor STL. Quando você deseja manter a alocação na pilha, considere boost::array
.
Qt
QPointer
- Introduzido no Qt 4.0, este é um ponteiro inteligente "fraco", que só funciona com QObject
classes derivadas e que, na estrutura do Qt, é quase tudo, então isso não é realmente uma limitação. No entanto, existem limitações, a saber, que ele não fornece um ponteiro "forte" e, embora você possa verificar se o objeto subjacente é válido, isNull()
poderá encontrar seu objeto sendo destruído logo após passar na verificação, especialmente em ambientes com vários segmentos. As pessoas Qt consideram isso obsoleto, acredito.
QSharedDataPointer
- Este é um ponteiro inteligente "forte", potencialmente comparável, boost::intrusive_ptr
embora tenha alguns recursos de segurança de encadeamento, mas exige que você inclua métodos de contagem de referência ( ref
e deref
) que você pode fazer subclassificando QSharedData
. Como em grande parte do Qt, os objetos são mais bem utilizados por meio de uma ampla herança e subclasse de tudo parece ser o design pretendido.
QExplicitlySharedDataPointer
- Muito parecido, QSharedDataPointer
exceto que não implica implicitamente detach()
. Eu chamaria essa versão 2.0 de QSharedDataPointer
que esse pequeno aumento no controle sobre exatamente quando desanexar após a contagem de referência cair para zero não vale particularmente a pena um objeto totalmente novo.
QSharedPointer
- Contagem de referência atômica, ponteiro seguro, ponteiro compartilhável, exclusões personalizadas (suporte a array), parece tudo o que um ponteiro inteligente deve ser. Isto é o que eu uso principalmente como um ponteiro inteligente no Qt e acho comparável com, boost:shared_ptr
embora provavelmente significativamente mais sobrecarga, como muitos objetos no Qt.
QWeakPointer
- Você sente um padrão recorrente? Assim como std::weak_ptr
e boost::weak_ptr
isso é usado em conjunto com QSharedPointer
quando você precisa de referências entre dois ponteiros inteligentes que, de outra forma, causariam a exclusão de seus objetos.
QScopedPointer
- Esse nome também deve parecer familiar e, na verdade, foi baseado nas boost::scoped_ptr
versões Qt de ponteiros compartilhados e fracos. Ele funciona para fornecer um ponteiro inteligente para um único proprietário, sem a sobrecarga, o QSharedPointer
que o torna mais adequado para compatibilidade, código de exceção seguro e tudo o que você pode usar std::auto_ptr
ou boost::scoped_ptr
para.