Question

J'ai été ressassant l'utilisation de unique_ptr vs shared_ptr vs own_solution.J'ai actualisé le dernier que je vais presque certainement se tromper, mais j'ai un problème avec les deux unique_ptr et shared_ptr en ce que ni capte précisément ce que je veux.Je veux créer un gestionnaire de ressources qui sont explicitement possède une ressource, cependant j'aimerais le gestionnaire de ressources à la main également des références à la ressource.

Si j'utilise unique_ptr dans le gestionnaire de ressources et de la main bruts des pointeurs, il y a la possibilité qu'ils pourraient s'échapper ailleurs (bien que cela irait à l'encontre de la classe "contrat", je suppose).Si j'utilise shared_ptr et la main weak_ptr, il n'y a rien d'arrêter l'appelant à partir de la conversion de la weak_ptr pour un shared_ptr et la sauvegarde, ce qui permet potentiellement de la création d'un cycle ou pire, une ressource de la vie au-delà de la durée de vie du gestionnaire de ressources.Donc je suppose que ce que je suis à la recherche d'un deferencable weak_ptr qui ne peut pas être converti en un shared_ptr.

Ou suis-je tout simplement qui cherchent à exécuter un contrat avec certains fortement exprimé des commentaires dans le code?

Merci pour toutes les pensées que vous pourriez avoir sur ce point.

Était-ce utile?

La solution

Pointeurs intelligents comme shared_ptr et unique_ptr sont un bon outil lorsque vous avez posséder les pointeurs.
Mais pour les non-posséder des pointeurs, c'est à dire l'observation des pointeurs, à l'aide d'un pointeur brut est tout simplement parfait.

Dans votre dessin, je pense que le gestionnaire de ressources est le seul "propriétaire" des ressources, de sorte que vous pouvez tout simplement une certaine forme de pointeur intelligent à l'intérieur de le gestionnaire de ressources.Par exemple, le gestionnaire de ressources peut avoir un std::vector<std::unique_ptr<Resource>> en tant que membre de données, ou même un simple std::vector<Resource> si votre Resource la classe est conçu pour être correctement stockés dans un std::vector.

Ensuite, le gestionnaire de ressources peut donner à l'extérieur de la non-possession d'observation des pointeurs, et des matières premières pointeurs (ou C++ références) sont très bien pour ce cas.

Bien sûr, il est important que la durée de vie du gestionnaire de ressources supérieure à celle de la ressource "clients".

Autres conseils

En fin de compte, vous ne pouvez pas forcer quelqu'un à l'écoute.Demander à microsoft, apple ou open source développeur de la bibliothèque, ils savent tous que la chanson.Un commentaire dans le droit des mots et des lieux est votre meilleur pari.

Éviter de créer votre propre pointeur intelligent de la classe, c'est une entrave à la composition et réduit la lisibilité.En dernier recours, essayez de rechercher dans boost, ou tout cadre de votre code a déjà de travailler avec.

Si vous avez des non-propriétaires, ils sont éligibles pour la tenue de weak_ptrs ou (si c'est la garantie de séjour valable pour la durée) les pointeurs.
Si vous utilisez shared_ptrs en interne (pourquoi devriez-vous), de fournir les meilleurs weak_ptr premières et des pointeurs.

Tous ces pointeurs intelligents explicitement désigner une politique de propriété.Raw pointeurs désigner aucun ou non propriétaire.

  • auto_ptr:Ne pas utiliser, obsolète avec trop de pièges, même pour les gardes.
  • unique_ptr:Propriété unique.
  • shared_ptr:La propriété partagée
  • weak_ptr:Aucun droit de propriété, peuvent être effacés derrière votre dos.
  • pointeur brut
    • Explicitement aucun droit de propriété avec une garantie de plus grande durée de vie
    • ou manuel de la gestion de la propriété.

Donc je suppose que ce que je suis à la recherche d'un deferencable weak que ne peut pas être converti en un shared_ptr.

Vous pourriez distribuer votre un peu de la classe helper:

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_;
};

C'est légèrement mieux qu'un pointeur brut, parce que vous pouvez vérifier si votre pointeur est toujours valide.

Exemple d'utilisation:

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

Toutefois, un utilisateur peut toujours abuser par exemple avec std::shared_ptr<T> blah(&(*wp));, mais il faut un peu plus d'énergie criminelle.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top