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.
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:
- tworzy instancje typu
function_impl_concrete<void(int), unspecified_type>
(to oczywiście czas kompilacji) - tworzy nowy obiekt tego typu na stercie
- 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.
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