Funkcja wywołania zwrotnego to funkcja będąca argumentem, a nie parametrem w innej funkcji. Drugą funkcję można nazwać funkcją główną. W grę wchodzą więc dwie funkcje: główna funkcja i sama funkcja wywołania zwrotnego. Na liście parametrów funkcji principal znajduje się deklaracja funkcji zwrotnej bez jej definicji, podobnie jak deklaracje obiektów bez przypisania. Główna funkcja jest wywoływana z argumentami (w main()). Jednym z argumentów w wywołaniu funkcji głównej jest efektywna definicja funkcji zwrotnej. W C++ ten argument jest odwołaniem do definicji funkcji zwrotnej; to nie jest faktyczna definicja. Sama funkcja zwrotna jest w rzeczywistości wywoływana w ramach definicji funkcji głównej.
Podstawowa funkcja zwrotna w C++ nie gwarantuje asynchronicznego zachowania w programie in. Zachowanie asynchroniczne to prawdziwa zaleta schematu funkcji wywołania zwrotnego. W schemacie funkcji wywołania zwrotnego asynchronicznego wynik funkcji głównej powinien zostać uzyskany dla programu przed uzyskaniem wyniku funkcji wywołania zwrotnego. Można to zrobić w C++; jednak C++ ma bibliotekę o nazwie future, która gwarantuje zachowanie schematu asynchronicznej funkcji zwrotnejback.
W tym artykule wyjaśniono podstawowy schemat funkcji wywołania zwrotnego. Dużo jest z czystym C++. Jeśli chodzi o callback, wyjaśniono również podstawowe zachowanie przyszłej biblioteki. Do zrozumienia tego artykułu niezbędna jest podstawowa znajomość C++ i jego wskaźnikówers.
Treść artykułu
- Podstawowy schemat funkcji oddzwaniania
- Zachowanie synchroniczne z funkcją oddzwaniania
- Zachowanie asynchroniczne z funkcją wywołania zwrotnego
- Podstawowe użytkowanie przyszłej Biblioteki
- Wniosek
Podstawowy schemat funkcji oddzwaniania
Schemat funkcji zwrotnej wymaga głównej funkcji, a sama funkcja zwrotna. Deklaracja funkcji zwrotnej jest częścią listy parametrów funkcji głównej. Definicja funkcji zwrotnej jest wskazana w wywołaniu funkcji funkcji głównej. Funkcja wywołania zwrotnego jest faktycznie wywoływana w ramach definicji funkcji głównej. Poniższy program ilustruje to:
#zawieraćprzy użyciu standardowej przestrzeni nazw;
int principalFn(char ch[], int (*ptr)(int))
int id1 = 1;
int id2 = 2;
int idr = (*ptr)(id2);
Cout<<"principal function: "<
int cb(identyfikator int)
Cout<<"callback function"<<'\n';
identyfikator powrotu;
int main()
int (*ptr)(int) = &cb;
char cha[] = "i";
głównyFn(cha, cb);
zwróć 0;
Dane wyjściowe to:
funkcja oddzwanianiagłówna funkcja: 1 i 2
Główna funkcja jest identyfikowana przez principalFn(). Funkcja zwrotna jest identyfikowana przez cb(). Funkcja wywołania zwrotnego jest zdefiniowana poza funkcją principal, ale w rzeczywistości jest wywoływana w funkcji principal.
Zwróć uwagę na deklarację funkcji zwrotnej jako parametr na liście parametrów deklaracji funkcji głównej. Deklaracja funkcji zwrotnej to „int (*ptr)(int)”. Zwróć uwagę na wyrażenie funkcji zwrotnej, podobnie jak wywołanie funkcji, w definicji funkcji głównej; jest tam przekazywany dowolny argument dla wywołania funkcji zwrotnej. Instrukcja dla tego wywołania funkcji to:
int idr = (*ptr)(id2);Gdzie id2 jest argumentem. ptr jest częścią parametru, wskaźnikiem, który będzie połączony z referencją funkcji zwrotnej w funkcji main().
Zwróć uwagę na wyrażenie:
int (*ptr)(int) = &cb;W funkcji main(), która łączy deklarację (bez definicji) funkcji zwrotnej z nazwą definicji tej samej funkcji zwrotnej.
Główna funkcja jest wywoływana w funkcji main() jako:
głównyFn(cha, cb);Gdzie cha jest napisem, a cb jest nazwą funkcji zwrotnej bez żadnego jej argumentu.
Synchroniczne zachowanie funkcji wywołania zwrotnego
Rozważ następujący program:
#zawieraćprzy użyciu standardowej przestrzeni nazw;
nieważny głównyFn(nieważny (*ptr)())
Cout<<"principal function"<<'\n';
(*ptr)();
nieważne cb()
Cout<<"callback function"<<'\n';
nieważne fn()
Cout<<"seen"<<'\n';
int main()
nieważne (*ptr)() = &cb;
głównyFn(cb);
fn();
zwróć 0;
Dane wyjściowe to:
główna funkcjafunkcja oddzwaniania
widziany
Jest tu nowa funkcja. Wszystko, co robi nowa funkcja, to wyświetlanie danych wyjściowych „widzianych”. W funkcji main() wywoływana jest funkcja główna, a następnie wywoływana jest nowa funkcja fn(). Wynik pokazuje, że kod dla funkcji głównej został wykonany, następnie dla funkcji zwrotnej, a na końcu dla funkcji fn(). Jest to zachowanie synchroniczne (jednowątkowe).
Gdyby było to zachowanie asynchroniczne, gdy trzy segmenty kodu są wywoływane w kolejności, pierwszy segment kodu może zostać wykonany, po czym zamiast tego wykonać trzeci segment kodu, przed wykonaniem drugiego segmentu kodu.
Cóż, funkcję fn() można wywołać z definicji funkcji głównej, zamiast z funkcji main(), w następujący sposób:
#zawieraćprzy użyciu standardowej przestrzeni nazw;
nieważne fn()
Cout<<"seen"<<'\n';
nieważny głównyFn(nieważny (*ptr)())
Cout<<"principal function"<<'\n';
fn();
(*ptr)();
nieważne cb()
Cout<<"callback function"<<'\n';
int main()
nieważne (*ptr)() = &cb;
głównyFn(cb);
zwróć 0;
Dane wyjściowe to:
główna funkcjawidziany
funkcja oddzwaniania
Jest to imitacja zachowania asynchronicznego. To nie jest zachowanie asynchroniczne. To nadal jest zachowanie synchroniczne.
Również kolejność wykonywania segmentu kodu funkcji głównej i segmentu kodu funkcji zwrotnej można zamienić w definicji funkcji głównej. Poniższy program ilustruje to:
#zawieraćprzy użyciu standardowej przestrzeni nazw;
nieważny głównyFn(nieważny (*ptr)())
(*ptr)();
Cout<<"principal function"<<'\n';
nieważne cb()
Cout<<"callback function"<<'\n';
nieważne fn()
Cout<<"seen"<<'\n';
int main()
nieważne (*ptr)() = &cb;
głównyFn(cb);
fn();
zwróć 0;
Wyjście jest teraz,
funkcja oddzwanianiagłówna funkcja
widziany
Jest to również imitacja zachowania asynchronicznego. To nie jest zachowanie asynchroniczne. To nadal jest zachowanie synchroniczne. Prawdziwe zachowanie asynchroniczne można uzyskać, jak wyjaśniono w następnej sekcji lub za pomocą biblioteki, future.
Zachowanie asynchroniczne z funkcją wywołania zwrotnego
Pseudokod podstawowego schematu funkcji asynchronicznego wywołania zwrotnego to:
typ wyjścia;wpisz cb (typ wyjścia)
//sprawozdania
wpisz principalFn(typ wejścia, wpisz cb(typ wyjścia))
//sprawozdania
Zwróć uwagę na pozycje danych wejściowych i wyjściowych w różnych miejscach pseudokodu. Wejście funkcji zwrotnej jest jej wyjściem. Parametry funkcji głównej są parametrem wejściowym kodu ogólnego i parametrem funkcji zwrotnej. W tym schemacie można wykonać (wywołać) trzecią funkcję w funkcji main() przed odczytaniem wyjścia funkcji zwrotnej (nadal w funkcji main()). Poniższy kod ilustruje to:
#zawieraćprzy użyciu standardowej przestrzeni nazw;
znak *wyjście;
void cb(char out[])
wyjście = wyjście;
void principalFn(znak input[], void (*ptr)(znak[50]))
(*ptr)(wejście);
Cout<<"principal function"<<'\n';
nieważne fn()
Cout<<"seen"<<'\n';
int main()
char input[] = "funkcja wywołania zwrotnego";
void (*ptr)(char[]) = &cb;
głównyFn(wejście, cb);
fn();
Cout<