jak boost:: function I boost::bind działają

Nie lubię mieć magicznych pudełek rozrzuconych po całym kodzie...jak dokładnie te dwie klasy działają, aby w zasadzie dowolna funkcja była mapowana do obiektu funkcji, nawet jeśli funkcja ma zupełnie inny parametr ustawiony na jeden im przekazywany do boost::bind

Działa nawet z różnymi konwencjami wywołującymi (tj. metody member są __thiscall pod VC, ale" normalne " funkcje są zazwyczaj __cdecl lub __stdcall dla tych, które muszą być kompatybilne z C.

Author: manlio, 2009-02-09

1 answers

boost::function umożliwia Związanie jako parametru wszystkiego z operator() z odpowiednim podpisem, a wynik wiązania może być wywołany z parametrem int, więc może być związany z function<void(int)>.

Tak to działa (opis ten dotyczy zarówno std::function):

boost::bind(&klass::member, instance, 0, _1) zwraca taki obiekt

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

Gdzie return_type i int są wnioskowane z podpisu klass::member, A wskaźnik funkcji i parametr bound są faktycznie przechowywane w obiekcie, ale to nie ważne

Teraz, boost::function nie wykonuje żadnego sprawdzania typu: pobiera każdy obiekt i każdy podpis podany w parametrze szablonu i tworzy obiekt, który można wywołać zgodnie z Twoim podpisem i wywołuje obiekt. Jeśli to niemożliwe, jest to błąd kompilacji.

boost::function w rzeczywistości jest to obiekt podobny do tego:

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

Gdzie return_type i argument_type są wyodrębniane z Sig, a f są dynamicznie przydzielane na stercie. To jest potrzebne, aby umożliwić całkowicie niepowiązane obiekty o różnych rozmiarach wiążą się z boost::function.

function_impl jest po prostu klasą abstrakcyjną

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

Klasa, która wykonuje całą pracę, jest konkretną klasą wywodzącą się z boost::function. Istnieje jeden dla każdego typu obiektu, który przypisujesz 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); }
};

Oznacza to w Twoim przypadku przypisanie do funkcji boost:

  1. tworzy instancje typu function_impl_concrete<void(int), unspecified_type> (to oczywiście czas kompilacji)
  2. tworzy nowy obiekt tego typu na stercie
  3. przypisuje to obiekt do członu f boost:: function

Gdy wywołujesz obiekt function, wywołuje on wirtualną funkcję swojego obiektu implementacji, która skieruje wywołanie do oryginalnej funkcji.

Zastrzeżenie: zauważ, że nazwy w tym wyjaśnieniu są celowo wymyślone. Jakiekolwiek podobieństwo do prawdziwych osób lub postaci ... wiesz o tym. Celem było zilustrowanie zasad.

 94
Author: jpalecek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-12 13:14:54