Question

J'utilise largement boost:shared_ptr dans mon code.En fait, la plupart des objets alloués sur le tas sont détenus par un shared_ptr.Malheureusement, cela signifie que je ne peux pas passer this dans n'importe quelle fonction qui prend un shared_ptr.Considérez ce code :

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

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

Ici, nous avons deux problèmes.Premièrement, cela ne sera pas compilé car le constructeur T* pour 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 qui finira par conduire à 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 savez qu'il existe à l'intérieur d'une méthode sur l'un de ces objets ?L'utilisation de références intrusives compte-t-elle ma seule option ici ?

Était-ce utile?

La solution

Vous pouvez dériver de activer_shared_from_this puis vous pouvez utiliser "shared_from_this()" au lieu de "this" pour générer un pointeur partagé vers votre propre objet.

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 lors de la génération de threads à partir d'une fonction membre de boost::bind à shared_from_this() au lieu de cela.Cela garantira que l’objet ne soit pas libéré.

Autres conseils

Utilisez simplement un pointeur brut pour votre paramètre de fonction au lieu de shared_ptr. L'objectif d'un pointeur intelligent est de contrôler la durée de vie de l'objet, mais celle-ci est déjà garantie par les règles de cadrage C ++: elle existera au moins aussi longtemps que la fin de votre fonction. Autrement dit, le code d'appel ne peut éventuellement supprimer l'objet avant le retour de votre fonction; donc la sécurité d'un " dumb " le pointeur est garanti tant que vous n'essayez pas de supprimer l'objet dans votre fonction.

La seule fois où vous avez besoin de passer un shared_ptr dans une fonction, c’est lorsque vous voulez transférer la propriété de l’objet à la fonction ou que la fonction copie le pointeur.

boost a une solution pour ce cas d'utilisation, consultez enable_shared_from_this

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


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

Avec C ++ 11 shared_ptr et enable_shared_from_this se trouvent maintenant dans la bibliothèque standard. Ce dernier est, comme son nom l'indique, exactement dans ce cas.

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

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

Exemple basé sur celui des 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';

La fonction qui accepte un pointeur souhaite appliquer l'un des deux comportements suivants:

  • Propriétaire de l'objet transmis et supprimez-le lorsqu'il sort de la portée. Dans ce cas, vous pouvez simplement accepter X * et envelopper immédiatement un scoped_ptr autour de cet objet (dans le corps de la fonction). Cela fonctionnera pour accepter & Quot; this & Quot; ou, en général, tout objet alloué par tas.
  • Partagez un pointeur (ne le possédez pas) avec l'objet transmis. Dans ce cas, vous ne souhaitez pas utiliser du tout un scoped_ptr, car ne veut pas supprimer l'objet à la fin de votre fonction. Dans ce cas, ce que vous voulez théoriquement, c'est un shared_ptr (je l'ai déjà vu appelé linked_ptr ailleurs). La bibliothèque boost a une version de shared_ptr , et cela est également recommandé dans le livre Effective C ++ de Scott Meyers (élément 18 de la 3ème édition).

Modifier: Oups, j'ai légèrement mal interprété la question et je vois maintenant que cette réponse ne répond pas exactement à la question. De toute façon, je vais en rester là, au cas où cela pourrait être utile à quiconque travaille avec un code similaire.

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