Pergunta

Nós praticamente se moveu para usando boost::shared_ptr em todo o nosso código, no entanto, ainda temos alguns casos isolados, onde usamos std::auto_ptr, incluindo aulas únicas:

template < typename TYPE >
class SharedSingleton
{
public: 
    static TYPE& Instance()
    {
        if (_ptrInstance.get() == NULL)
            _ptrInstance.reset(new TYPE);
        return *_ptrInstance;
    }

protected: 
    SharedSingleton() {};

private:
    static std::auto_ptr < TYPE > _ptrInstance;
};

Eu tenho dito que há uma boa razão por que isso não foi feito um shared_ptr, mas para a vida de mim eu não consigo entender por quê? Eu sei que auto_ptr acabará por se marcado como depreciado no próximo padrão, então eu gostaria de sabe o que / como posso substituir essa implementação .

Além disso, existem outras razões por que você iria considerar o uso de um auto_ptr em vez de um shared_ptr? E você vê nenhum problema de se mudar para shared_ptr no futuro?


Editar:

  1. Assim, em resposta à pergunta "posso com segurança substituir auto_ptr com shared_ptr no código acima", a resposta é sim -. No entanto eu vou ter um pequeno impacto no desempenho
  2. Quando auto_ptr eventualmente é marcado como depreciado e nós passar para std::shared_ptr, vamos precisar para testar exaustivamente o nosso código para se certificar de que estamos respeitando as diferentes semântica de propriedade.
Foi útil?

Solução

auto_ptr e shared_ptr resolver completamente diferentes problemas. Um não substitui o outro.

auto_ptr é um wrapper fino ao redor ponteiros para implementar RAII semântica, para que os recursos são sempre liberados , mesmo diante exceções. auto_ptr não executa nenhuma contagem de referência ou similares em tudo, não faz vários ponteiros apontam para o mesmo objeto ao criar cópias. Na verdade, é muito diferente. auto_ptr é uma das poucas classes, onde o operador de atribuição modifica o origem objeto. Considere este plug descarado do auto_ptr wikipedia página :

int *i = new int;
auto_ptr<int> x(i);
auto_ptr<int> y;

y = x;

cout << x.get() << endl; // Print NULL
cout << y.get() << endl; // Print non-NULL address i

Observe como executar

y = x;

modifica não só y mas também x.

O modelo boost::shared_ptr torna mais fácil de lidar com vários ponteiros para o mesmo objeto, e o objeto só é eliminado após a última referência a ele saiu do escopo. Este recurso não é útil em seu cenário, que (tentativas de) implementar um Singleton . No seu cenário, há sempre quer 0 referências a 1 de referência para o único objeto da classe, se for o caso.

Em essência, objetos auto_ptr e objetos shared_ptr têm completamente diferentes semântica (é por isso que você não pode usar o antigo em recipientes, mas fazê-lo com o último é bom), e eu com certeza espero que você tenha bons testes para capturar qualquer regressões você introduzidas enquanto portar seu código. : -}

Outras dicas

Outros têm respondido por que esse código usa um auto_ptr em vez de um shared_ptr. Para lidar com suas outras perguntas:

O que / como posso substituir essa implementação?

Use quer boost::scoped_ptr ou unique_ptr (disponível tanto em Boost e o novo C ++ padrão). Ambos scoped_ptr e unique_ptr fornecer propriedade estrito (e nenhuma sobrecarga de contagem de referência), andthey evitar os surpreendentes semântica delete-on-copy de auto_ptr.

Além disso, existem outras razões por que você iria considerar o uso de um auto_ptr em vez de um shared_ptr? E você vê nenhum problema de se mudar para shared_ptr no futuro?

Pessoalmente, eu não iria usar um auto_ptr. Excluir-on-cópia é muito não-intuitivo. Herb Sutter parece concordar . Mudar para scoped_ptr, unique_ptr, ou shared_ptr deve oferecer nenhum problema. Especificamente, shared_ptr deve ser um substituto se você não se preocupam com a sobrecarga de contagem de referência. scoped_ptr é um substituto se você não estiver usando recursos de transferência de propriedade de auto_ptr. Se você estiver usando a transferência de propriedade, então unique_ptr é quase um substituto, exceto que você precisa chamar em vez explicitamente move para transferir a propriedade. Consulte aqui para um exemplo.

auto_ptr é o único tipo de uso inteligente ponteiro I. Eu usá-lo porque eu não usar Boost, e porque eu geralmente preferem meus negócios aulas / orientadas para a aplicação explicitamente definir semântica de deleção e ordem, ao invés de depender coleções de, ou, ponteiros inteligentes individuais.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top