82 votes

fonctionnement des boost::function et boost::bind

Je n'aime pas avoir des boîtes de la magie partout dans mon code...comment exactement ces deux classes de travail pour permettre fondamentalement, toute fonction à associer à une fonction d'objet, même si la fonction<> est complètement différent de ce paramètre est défini à l'une im passage à l' boost::bind

Il fonctionne même avec les différentes conventions d'appel (c'est à dire membre de méthodes sont __thiscall sous VC, mais "normale", les fonctions sont généralement __cdecl ou __stdcall pour ceux qui ont besoin d'être compatible avec C.

95voto

jpalecek Points 31928

boost::function permet à quoi que ce soit avec un operator() avec le bouton droit de signature à être lié comme paramètre, et le résultat de votre bind peut être appelée avec un paramètre int, de sorte qu'il peut être lié à l' function<void(int)>.

Voilà comment cela fonctionne (cette description s'applique aussi bien pour l' std::function):

boost::bind(&klass::member, instance, 0, _1) renvoie un objet comme celui-ci

struct unspecified_type
{
  ... some members ...
  return_type operator()(int i) const { return instance->*&klass::member(0, i);
}

où l' return_type et int sont déduits à partir de la signature de l' klass::member, et le pointeur de fonction et paramètre de limite sont en fait stockées dans l'objet, mais ce n'est pas important

Maintenant, boost::function n'est pas n'importe quel type de vérification: Il faudra tout objet et de toute signature vous fournir dans son paramètre du modèle, et de créer un objet appelable en fonction de votre signature et appelle l'objet. Si c'est impossible, c'est une erreur de compilation.

boost::function est en fait un objet comme ceci:

template <class Sig>
class function
{
  function_impl<Sig>* f;
public:
  return_type operator()(argument_type arg0) const { return (*f)(arg0); }
};

où l' return_type et argument_type sont extraits d' Sig, et f est allouée dynamiquement sur le tas. C'est nécessaire pour permettre complètement indépendants des objets avec différentes tailles de lier boost::function.

function_impl est juste une classe abstraite

template <class Sig>
class function_impl
{
public:
  virtual return_type operator()(argument_type arg0) const=0;
};

La classe qui fait tout le travail, est un béton de classe dérivée de l' boost::function. Il y en a un pour chaque type d'objet que vous attribuez à boost::function

template <class Sig, class Object>
class function_impl_concrete : public function_impl<Sig>
{
  Object o
public:
  virtual return_type operator()(argument_type arg0) const=0 { return o(arg0); }
};

Cela signifie que dans votre cas, l'affectation à la fonction "boost":

  1. instancie un type function_impl_concrete<void(int), unspecified_type> (c'est le moment de la compilation, bien sûr)
  2. crée un nouvel objet de ce type sur le tas
  3. attribue cet objet au f membre de boost::function

Lorsque vous appelez la fonction de l'objet, il appelle la fonction virtuelle de sa mise en œuvre, de l'objet, qui va diriger l'appel vers votre fonction d'origine.

AVERTISSEMENT: veuillez Noter que les noms de cette explication sont volontairement. Toute ressemblance avec des personnes réelles ou des personnages ... vous le savez. Le but était d'illustrer les principes.

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