Question

Je travaille sur une classe de gestion des ressources et souhaite que l'utilisateur fournisse un foncteur à un "ReleaseResource". méthode dans le cadre du constructeur du gestionnaire de ressources. À partir de là, lorsqu'une ressource est demandée, functor sera fourni en tant que supprime pour le shared_ptr que je renverrai, de sorte que la méthode appropriée sera appelée lorsque la ressource ne sera plus utilisée.

Le problème que je rencontre est que cela nécessite que je stocke le foncteur dans ma classe et je ne sais pas trop comment faire. Généralement, lorsque vous utilisez un foncteur, vous modélisez la fonction comme suit:

template<class MyFunctor> MyMethod(MyFunctor f) {
    f();
}

Ce qui est bien si vous envisagez d'utiliser le foncteur dans le cadre de cette fonction, mais comme le modèle est hors de portée avec la fonction, je ne sais pas comment vous spécifieriez une variable du type approprié pour stocker le foncteur. pour une utilisation ultérieure.

Quelqu'un peut-il m'indiquer la bonne direction ici?

Était-ce utile?

La solution

template<class MyFunctor> MyMethod(MyFunctor f) {
    boost::function<void()> g = f;
    g();
}

Le type que vous transmettez à boost :: function est le type de fonction. Par exemple, int (bool, char) est le type d'une fonction renvoyant int et prenant bool et char. Cela dit, si vous voulez construire immédiatement le shared_ptr, vous n’avez pas besoin de stocker le foncteur ( boost :: function requiert l’opérateur new pour cela, même mais pour les très petits foncteurs, il utilisera des astuces spéciales pour utiliser uniquement l’allocation de pile (optimisation de la mémoire tampon)):

template<class MyFunctor> MyMethod(MyFunctor f) {
    boost::shared_ptr<T> ptr(new T, f);
}

boost :: function fait partie de tr1 et sera fait partie de la prochaine norme officielle C ++. Exemple:

struct Manager {
    template<typename Deleter>
    Manager(Deleter d) 
        :deleter(d) {

    }

    boost::shared_ptr<Resource> allocate() {
        ...
        return boost::shared_ptr<Resource>(resource, deleter);
    }

private:
    boost::function<void(Resource *)> deleter;
};

Autres conseils

Il existe deux méthodes, l'une et l'autre permettant de modéliser la classe.

template <MyFunctor>
class MyClass
{
   MyFunctor   func;
  public:
    MyClass(MyFunctor f) :func(f)
    { }


    MyMethod() 
   {
       func();
   }
}

Ceci vous obligerait à connaître le type de foncteur. Pour éviter cela, nous pouvons utiliser une usine:

 template<MyFunctor>
 MyClass<MyFunctor>  MakeFunctorClass(MyFunctor f)
 {     
     return MyClass<MyFunctor>(f);       
 }

Alternativement, étant donné que, selon toute vraisemblance, la signature du foncteur sera en grande partie identique, avec seulement une petite partie qui change, nous pourrions l'utiliser:

template <MyType>
class MyClass
{
   typedef std::binary_function<MyType, MyType, bool>  MyFunctor;
   MyFunctor func;
  public:


    MyMethod(MyFunctor f) 
   {
       func = f;
       func();
   }
}

Cela simplifie un peu l'utilisation:

 bool AreEqual(int, int); 
 MyClass<int> myc;
 myc.MyMethod(AreEqual);

au prix d’une définition plus complexe (c’est-à-dire que je ne garantis pas que le typedef de fonction-binaire que j’ai donné fonctionnera)

Je ne sais pas si cela aiderait, mais sachez que boost :: shared_ptr possède des substitutions de constructeur qui permettent à l'utilisateur d'inclure une désaffectation (et un allocateur personnalisé, si vous le souhaitez). Cela peut suffire à vos besoins (il a été conçu dans cet esprit, si je lis correctement votre cas d'utilisation).

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