Funkcia spätného volania v C ++

Callback Function C



Funkcia spätného volania je funkcia, ktorá je argumentom, nie parametrom, v inej funkcii. Druhú funkciu možno nazvať hlavnou funkciou. Zahrnuté sú teda dve funkcie: hlavná funkcia a samotná funkcia spätného volania. V zozname parametrov hlavnej funkcie je prítomná deklarácia funkcie spätného volania bez jej definície, rovnako ako sú prítomné deklarácie objektov bez priradenia. Hlavná funkcia sa volá s argumentmi (v main ()). Jeden z argumentov vo volaní hlavnej funkcie je účinná definícia funkcie spätného volania. V C ++ je tento argument odkazom na definíciu funkcie spätného volania; nie je to skutočná definícia. Samotná funkcia spätného volania sa v skutočnosti nazýva v rámci definície hlavnej funkcie.

Základná funkcia spätného volania v C ++ nezaručuje asynchrónne správanie v programe. Asynchrónne správanie je skutočnou výhodou schémy funkcií spätného volania. V schéme funkcie asynchrónneho spätného volania by sa mal pre program získať výsledok hlavnej funkcie pred získaním výsledku funkcie spätného volania. Je to možné urobiť v C ++; C ++ však má knižnicu s názvom future, ktorá zaručuje správanie schémy funkcií asynchrónneho spätného volania.







Tento článok vysvetľuje základnú schému funkcie spätného volania. Veľa z toho je v čistom C ++. Pokiaľ ide o spätné volanie, je tiež vysvetlené základné správanie budúcej knižnice. Základné znalosti C ++ a jeho ukazovateľov sú nevyhnutné pre pochopenie tohto článku.



Obsah článku

Základná schéma funkcie spätného volania

Schéma funkcie spätného volania potrebuje hlavnú funkciu a samotnú funkciu spätného volania. Deklarácia funkcie spätného volania je súčasťou zoznamu parametrov hlavnej funkcie. Definícia funkcie spätného volania je uvedená vo volaní funkcie hlavnej funkcie. Funkcia spätného volania sa v skutočnosti volá v rámci definície hlavnej funkcie. Nasledujúci program to ilustruje:



#zahrnúť

použitím priestor mienhodiny;



intmainFn(charch[],int (*ptr)(int))

{

intid1= 1;

intid2= 2;

intzvyčajne= (*ptr)(id2);

náklady<<'hlavná funkcia:'<<id1<<''<<ch<<''<<zvyčajne<<' n';

vrátiť said1;

}


intcb(intiden)

{

náklady<<'funkcia spätného volania'<<' n';

vrátiť saiden;

}


intHlavná()

{

int (*ptr)(int) = &cb;

charč[] = 'a';

mainFn(otec, cb);



vrátiť sa 0;

}

Výstupom je:





funkcia spätného volania

hlavná funkcia: 1 a 2

Hlavná funkcia je identifikovaná príkazom principalFn (). Funkcia spätného volania je identifikovaná cb (). Funkcia spätného volania je definovaná mimo hlavnej funkcie, ale v skutočnosti sa volá v rámci hlavnej funkcie.

Všimnite si deklaráciu funkcie spätného volania ako parametra v zozname parametrov deklarácie hlavnej funkcie. Deklarácia funkcie spätného volania je int (*ptr) (int). Všimnite si výraz funkcie spätného volania, podobne ako volanie funkcie, v definícii hlavnej funkcie; je tam odovzdaný akýkoľvek argument pre volanie funkcie spätného volania. Príkaz pre toto volanie funkcie je:



intzvyčajne= (*ptr)(id2);

Kde id2 je argument. ptr je súčasťou parametra, ukazovateľa, ktorý bude prepojený s odkazom na funkciu spätného volania vo funkcii main ().

Všimnite si výrazu:

int (*ptr)(int) = &cb;

Vo funkcii main (), ktorá spája deklaráciu (bez definície) funkcie spätného volania s názvom definície tej istej funkcie spätného volania.

Hlavná funkcia sa vo funkcii main () nazýva:

mainFn(otec, cb);

Kde cha je reťazec a cb je názov funkcie spätného volania bez akéhokoľvek jej argumentu.

Synchrónne správanie funkcie spätného volania

Zvážte nasledujúci program:

#zahrnúť

použitím priestor mienhodiny;



prázdnymainFn(prázdny (*ptr)())

{

náklady<<„hlavná funkcia“<<' n';

(*ptr)();

}


prázdnycb()

{

náklady<<'funkcia spätného volania'<<' n';

}


prázdnyfn()

{

náklady<<'videl'<<' n';

}


intHlavná()

{

prázdny (*ptr)() = &cb;

mainFn(cb);

fn();



vrátiť sa 0;

}

Výstupom je:

hlavná funkcia

funkcia spätného volania

vidieť

Je tu nová funkcia. Všetko, čo nová funkcia robí, je zobraziť výstup, ktorý vidíte. Vo funkcii main () sa nazýva hlavná funkcia a potom sa volá nová funkcia fn (). Výstup ukazuje, že bol vykonaný kód pre hlavnú funkciu, potom pre funkciu spätného volania a nakoniec pre funkciu fn (). Toto je synchrónne (jednovláknové) správanie.

Ak by išlo o asynchrónne správanie, keď sú tri kódové segmenty volané v poradí, môže byť vykonaný prvý segment kódu, namiesto toho nasleduje vykonanie tretieho segmentu kódu pred vykonaním druhého segmentu kódu.

Funkciu fn () je možné zavolať z definície hlavnej funkcie, a nie z funkcie main (), a to takto:

#zahrnúť

použitím priestor mienhodiny;



prázdnyfn()

{

náklady<<'videl'<<' n';

}


prázdnymainFn(prázdny (*ptr)())

{

náklady<<„hlavná funkcia“<<' n';

fn();

(*ptr)();

}


prázdnycb()

{

náklady<<'funkcia spätného volania'<<' n';

}


intHlavná()

{

prázdny (*ptr)() = &cb;

mainFn(cb);



vrátiť sa 0;

}

Výstupom je:

hlavná funkcia

vidieť

funkcia spätného volania

Toto je napodobenina asynchrónneho správania. Nie je to asynchrónne správanie. Stále je to synchrónne správanie.

V definícii hlavnej funkcie je tiež možné zameniť poradie vykonania segmentu kódu hlavnej funkcie a segmentu kódu funkcie spätného volania. Nasledujúci program to ilustruje:

#zahrnúť

použitím priestor mienhodiny;



prázdnymainFn(prázdny (*ptr)())

{

(*ptr)();

náklady<<„hlavná funkcia“<<' n';

}


prázdnycb()

{

náklady<<'funkcia spätného volania'<<' n';

}


prázdnyfn()

{

náklady<<'videl'<<' n';

}


intHlavná()

{

prázdny (*ptr)() = &cb;

mainFn(cb);

fn();



vrátiť sa 0;

}

Výstup je teraz,

funkcia spätného volania

hlavná funkcia

vidieť

Toto je tiež napodobenina asynchrónneho správania. Nie je to asynchrónne správanie. Stále je to synchrónne správanie. Skutočné asynchrónne správanie je možné získať tak, ako je vysvetlené v nasledujúcej časti alebo pomocou knižnice, budúcnosť.

Asynchrónne správanie s funkciou spätného volania

Pseudokód pre základnú schému funkcie asynchrónneho spätného volania je:

typový výstup;

typ cb(typový výstup)

{

//Vyhlásenia

}


zadajte principálFn(zadajte vstup, zadajte cb(typový výstup))

{

//Vyhlásenia

}

Všimnite si polohy vstupných a výstupných údajov na rôznych miestach pseudokódu. Vstupom funkcie spätného volania je jej výstup. Parametre hlavnej funkcie sú vstupným parametrom pre všeobecný kód a parametrom funkcie spätného volania. V tejto schéme je možné vykonať (zavolať) tretiu funkciu vo funkcii main () pred tým, ako sa načíta výstup funkcie spätného volania (stále vo funkcii main ()). Nasledujúci kód to ilustruje:

#zahrnúť

použitím priestor mienhodiny;

char *výkon;


prázdnycb(charvon[])

{

výkon=von;

}



prázdnymainFn(charvstup[],prázdny (*ptr)(char[päťdesiat]))

{

(*ptr)(vstup);

náklady<<„hlavná funkcia“<<' n';

}


prázdnyfn()

{

náklady<<'videl'<<' n';

}


intHlavná()

{

charvstup[] = 'funkcia spätného volania';

prázdny (*ptr)(char[]) = &cb;

mainFn(vstup, cb);

fn();

náklady<<výkon<<' n';



vrátiť sa 0;

}

Výstup programu je:

hlavná funkcia

vidieť

funkcia spätného volania

V tomto konkrétnom kóde je výstupný a vstupný nulový bod rovnaký. Výsledok tretieho volania funkcie vo funkcii main () bol zobrazený pred výsledkom funkcie spätného volania. Funkcia spätného volania sa spustila, dokončila a priradila svoj výsledok (hodnotu) premennej, výstup, čo umožňuje programu pokračovať bez rušenia. Vo funkcii main () bol výstup funkcie spätného volania použitý (prečítaný a zobrazený), keď bol potrebný, čo viedlo k asynchrónnemu správaniu celej schémy.

Toto je jednovláknový spôsob, ako získať asynchrónne správanie funkcie spätného volania v čistom jazyku C ++.

Základné využitie budúcej knižnice

Myšlienka schémy funkcie asynchrónneho spätného volania spočíva v tom, že sa hlavná funkcia vráti skôr, ako sa funkcia spätného volania vráti. Toto sa uskutočnilo nepriamo, efektívne, vo vyššie uvedenom kóde.

Všimnite si toho z vyššie uvedeného kódu, že funkcia spätného volania prijíma hlavný vstup pre kód a vytvára hlavný výstup pre kód. Knižnica C ++, budúcnosť, má funkciu nazývanú sync (). Prvým argumentom pre túto funkciu je odkaz na funkciu spätného volania; druhý argument je vstupom do funkcie spätného volania. Funkcia sync () sa vráti bez čakania na dokončenie vykonania funkcie spätného volania, ale umožní dokončenie funkcie spätného volania. To poskytuje asynchrónne správanie. Aj keď sa funkcia spätného volania naďalej vykonáva, pretože funkcia sync () sa už vrátila, nižšie uvedené príkazy sa vykonávajú. Je to ako ideálne asynchrónne správanie.

Vyššie uvedený program bol nižšie prepísaný s prihliadnutím na budúcu knižnicu a jej funkciu sync ():

#zahrnúť

#zahrnúť

#zahrnúť

použitím priestor mienhodiny;

budúcnosť<reťazec>výkon;

reťazec cb(šnúrka stri)

{

vrátiť sastri;

}



prázdnymainFn(reťazcový vstup)

{

výkon=asynchr(cb, vstup);

náklady<<„hlavná funkcia“<<' n';

}


prázdnyfn()

{

náklady<<'videl'<<' n';

}


intHlavná()

{

reťazcový vstup=reťazec('funkcia spätného volania');

mainFn(vstup);

fn();

retazec ret=výkon.dostať(); // čaká na návrat spätného volania, ak je to potrebné

náklady<<správny<<' n';



vrátiť sa 0;

}

Funkcia sync () nakoniec uloží výstup funkcie spätného volania do budúceho objektu. Očakávaný výstup je možné získať vo funkcii main () pomocou členskej funkcie get () budúceho objektu.

Záver

Funkcia spätného volania je funkcia, ktorá je argumentom, nie parametrom, v inej funkcii. Schéma funkcie spätného volania potrebuje hlavnú funkciu a samotnú funkciu spätného volania. Deklarácia funkcie spätného volania je súčasťou zoznamu parametrov hlavnej funkcie. Definícia funkcie spätného volania je uvedená vo volaní funkcie hlavnej funkcie (v main ()). Funkcia spätného volania sa v skutočnosti volá v rámci definície hlavnej funkcie.

Schéma funkcie spätného volania nemusí byť nevyhnutne asynchrónna. Aby ste sa uistili, že schéma funkcie spätného volania je asynchrónna, zadajte hlavný vstup do kódu, vstup do funkcie spätného volania; urobte hlavný výstup kódu, výstup funkcie spätného volania; uložiť výstup funkcie spätného volania do variabilnej alebo dátovej štruktúry. Vo funkcii main () po zavolaní hlavnej funkcie vykonajte ďalšie príkazy aplikácie. Keď je potrebný výstup funkcie spätného volania, vo funkcii main () ho použite (prečítajte a zobrazte) tam a potom.