76 votes

Obtenir un boost::shared_ptr pour cela

Je fais un usage intensif de boost:shared_ptr dans mon code. En fait, la plupart des objets qui sont alloués sur le tas sont détenus par un objet shared_ptr . Malheureusement, cela signifie que je ne peux pas passer this dans toute fonction qui prend un shared_ptr . Considérez ce code :

void bar(boost::shared_ptr<Foo> pFoo)
{
    ...
}

void Foo::someFunction()
{
    bar(this);
}

Il y a deux problèmes ici. D'abord, cela ne compilera pas parce que le constructeur T* de shared_ptr est explicite. Deuxièmement, si je le force à construire avec bar(boost::shared_ptr<Foo>(this)) J'aurai créé un deuxième pointeur partagé vers mon objet, ce qui conduira éventuellement à une double-suppression.

Cela m'amène à ma question : Existe-t-il un modèle standard pour obtenir une copie du pointeur partagé existant dont vous connaissez l'existence à l'intérieur d'une méthode sur un de ces objets ? Est-ce que l'utilisation d'un comptage de référence intrusif est ma seule option ici ?

102voto

Brian R. Bondy Points 141769

Vous pouvez dériver de enable_shared_from_this et ensuite vous pouvez utiliser "shared_from_this()" au lieu de "this" pour créer un pointeur partagé vers votre propre objet self.

Exemple dans le lien :

#include <boost/enable_shared_from_this.hpp>

class Y: public boost::enable_shared_from_this<Y>
{
public:

    shared_ptr<Y> f()
    {
        return shared_from_this();
    }
}

int main()
{
    shared_ptr<Y> p(new Y);
    shared_ptr<Y> q = p->f();
    assert(p == q);
    assert(!(p < q || q < p)); // p and q must share ownership
}

C'est une bonne idée, lorsque l'on crée des threads à partir d'une fonction membre, d'utiliser boost::bind vers un shared_from_this() au lieu de this. Cela permet de s'assurer que l'objet n'est pas libéré.

19voto

Mark Ransom Points 132545

Utilisez simplement un pointeur brut pour votre paramètre de fonction au lieu du shared_ptr. Le but d'un pointeur intelligent est de contrôler la durée de vie de l'objet, mais la durée de vie de l'objet est déjà garantie par les règles de scoping du C++ : il existera au moins aussi longtemps que la fin de votre fonction. En d'autres termes, le code appelant ne peut pas supprimer l'objet avant le retour de votre fonction ; ainsi, la sécurité d'un pointeur "muet" est garantie, tant que vous n'essayez pas de supprimer l'objet dans votre fonction.

La seule fois où vous devez passer un shared_ptr dans une fonction est lorsque vous voulez transmettre la propriété de l'objet à la fonction, ou lorsque vous voulez que la fonction fasse une copie du pointeur.

14voto

David Pierre Points 5039

Boost a une solution pour ce cas d'utilisation. enable_shared_from_this

9voto

Greg Rogers Points 18119

Faites-vous vraiment plus de copies partagées de pFoo dans la barre ? Si vous ne faites rien de fou à l'intérieur, faites simplement ceci :

void bar(Foo &foo)
{
    // ...
}

5voto

Johan Lundberg Points 5835

Avec C++11 shared_ptr y enable_shared_from_this est maintenant dans la bibliothèque standard. Cette dernière est, comme son nom l'indique, exactement pour ce cas.

http://en.cppreference.com/w/cpp/memory/shared_ptr

http://en.cppreference.com/w/cpp/memory/enable_shared_from_this

Des bases d'exemples à ce sujet dans les liens ci-dessus :

struct Good: std::enable_shared_from_this<Good>{
    std::shared_ptr<Good> getptr() {
        return shared_from_this();
    }
};

utiliser :

std::shared_ptr<Good> gp1(new Good);
std::shared_ptr<Good> gp2 = gp1->getptr();
std::cout << "gp2.use_count() = " << gp2.use_count() << '\n';

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X