Pergunta

Estive meditando sobre o uso de unique_ptr vs shared_ptr vs own_solution.Eu já descontado o último, como eu vou quase certamente ser errado, mas eu tenho um problema com ambos unique_ptr e shared_ptr em que nem capta precisamente o que eu quero.Eu quero criar um gerenciador de recursos que explicitamente possui um recurso, no entanto, eu gostaria que o gerenciador de recursos de mão também as referências para o recurso.

Se eu usar unique_ptr no gerenciador de recursos e mão matérias ponteiros há a possibilidade de que possam escapar em outro lugar (apesar de que isso seria contra a classe "contrato" eu suponho).Se eu usar shared_ptr e do lado de fora weak_ptr, não há nada que impeça um chamador de converter o weak_ptr para um shared_ptr e armazenamento de que, potencialmente, assim, a criação de um ciclo ou, pior ainda, um recurso que vivem além do tempo de vida do gestor de recursos.Então eu suponho que o que eu estou procurando é uma deferencable weak_ptr que não pode ser convertida em shared_ptr.

Ou estou apenas olhando para executar o contrato com alguns fortemente redigida comentários no código?

Obrigado por todos os pensamentos que você pode ter sobre isso.

Foi útil?

Solução

Ponteiros inteligentes como shared_ptr e unique_ptr são boas ferramentas quando você tem possuir ponteiros.
Mas, por não possuir ponteiros, i.é. observando os ponteiros, usando um ponteiro bruto é apenas multa.

Em seu design, eu acho que o gestor de recursos é o único "dono" de recursos, então você poderia simplesmente ter alguma forma de ponteiro inteligente dentro o gerenciador de recursos.Por exemplo, o gerenciador de recursos pode ter um std::vector<std::unique_ptr<Resource>> como um membro de dados, ou até mesmo um mais simples std::vector<Resource> se o seu Resource classe é projetado para ser corretamente armazenados em um std::vector.

Em seguida, o gerenciador de recursos pode dar para o exterior só não possuir observando os ponteiros, e matérias de apontadores (ou C++ referências) são bons para este caso.

Claro, é importante que o tempo de vida do gerenciador de recursos de não exceder a dos "recursos de clientes".

Outras dicas

No final, você não pode forçar ninguém a ouvir.Pergunte a microsoft, apple ou qualquer biblioteca de código aberto do desenvolvedor, todos sabem que música.Um comentário em as palavras certas e lugares é a sua melhor aposta.

Evitar a criação de seu próprio ponteiro inteligente de classe, impede composição e reduz a legibilidade.Como último recurso, tente procurar no impulso, ou qualquer framework de código já tem para trabalhar.

Se você tem não-proprietários, eles são elegíveis para a realização de weak_ptrs ou (se é garantido para permanecer válido para a duração) matérias ponteiros.
Se você usar shared_ptrs internamente (por que você deve), melhor prestação de weak_ptr prima e de ponteiros.

Todos os ponteiros inteligentes explicitamente indicar uma política de propriedade.Matérias ponteiros denotar nenhum ou não possuir.

  • auto_ptr:Não use, preterido com muitas armadilhas, mesmo para o cuidado.
  • unique_ptr:Propriedade exclusiva.
  • shared_ptr:Propriedade compartilhada
  • weak_ptr:Nenhum direito de propriedade, podem ser suprimido por trás de suas costas.
  • matérias ponteiro
    • Explicitamente não há propriedade com garantia de maior vida útil
    • ou manual de gerenciamento de propriedade.

Então eu suponho que o que eu estou procurando é uma deferencable weak_ptr que não pode ser convertido em um shared_ptr.

Você poderia entregar a sua pequena classe auxiliar:

template<typename T>
class NonConvertibleWeakPtr
{
public:
   NonConvertibleWeakPtr(const std::shared_ptr<T>& p) : p_(p) {}
   ... // other constructors / assignment operators
   bool expired() const { return p_.expired(); }
   T* operator->() const { return get(); }
   T& operator*() const { return *get(); }
private:
   T* get() const { return p_.lock().get(); }
private:
   std::weak_ptr<T> p_;
};

Este é um pouco melhor do que uma matéria-prima de ponteiro, porque você pode verificar se o ponteiro ainda é válido.

Exemplo de uso:

std::shared_ptr<int> sp = std::make_shared<int>(5);
{
    NonConvertibleWeakPtr<int> wp(sp);
    if(!wp.expired()) {
        std::cout << *wp << std::endl;
    }
}

No entanto, um usuário pode ainda mau uso como, por exemplo, com std::shared_ptr<T> blah(&(*wp));, mas é preciso um pouco mais de criminal de energia.

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