Takaisinsoittotoiminto C ++: ssa

Callback Function C

Takaisinsoittotoiminto on funktio, joka on argumentti, ei parametri, toisessa funktiossa. Toista funktiota voidaan kutsua päätoiminnoksi. Kyseessä on siis kaksi toimintoa: päätoiminto ja itse takaisinsoittotoiminto. Päätoiminnon parametriluettelossa takaisinsoittotoiminnon ilmoitus ilman sen määritelmää on läsnä, aivan kuten objektin ilmoitukset ilman määrittämistä. Päätoimintoa kutsutaan argumentteilla (in main ()). Yksi päätoimintokutsun argumenteista on takaisinsoittotoiminnon tehokas määrittely. C ++: ssa tämä argumentti on viittaus takaisinsoittotoiminnon määritelmään; se ei ole varsinainen määritelmä. Itse takaisinsoittotoimintoa kutsutaan itse asiassa päätoiminnon määritelmän sisällä.

Perussoittotoiminto C ++: ssa ei takaa asynkronista toimintaa ohjelmassa. Asynkroninen käyttäytyminen on takaisinsoittotoimintojärjestelmän todellinen hyöty. Asynkronisessa takaisinsoittotoimintojärjestelmässä päätoiminnon tulos on hankittava ohjelmalle ennen takaisinsoittotoiminnon tuloksen saamista. Tämä on mahdollista C ++: ssa; C ++: lla on kuitenkin kirjasto nimeltä tulevaisuus, joka takaa asynkronisen takaisinsoittotoiminnon käyttäytymisen.



Tässä artikkelissa selitetään takaisinsoittotoimintojen perusmallit. Suuri osa siitä on puhtaalla C ++: lla. Takaisinsoiton osalta selitetään myös tulevan kirjaston peruskäyttäytyminen. Perustiedot C ++: sta ja sen osoittimista ovat välttämättömiä tämän artikkelin ymmärtämiseksi.



Artikkelin sisältö

Perussoittotoimintojärjestelmä

Takaisinsoittotoimintojärjestelmä tarvitsee päätoiminnon ja itse takaisinsoittotoiminnon. Takaisinsoittotoiminnon ilmoitus on osa päätoiminnon parametriluetteloa. Takaisinsoittotoiminnon määritelmä näkyy päätoiminnon funktiokutsussa. Takaisinsoittotoimintoa kutsutaan itse asiassa päätoiminnon määritelmän sisällä. Seuraava ohjelma havainnollistaa tätä:



#sisältää

käyttämällä nimiavaruustuntia;



intmainFn(hiiltyäch[],int (*ptr)(int))

{

intid1= 1;

intid2= 2;

intyleensä= (*ptr)(id2);

kustannus<<'päätehtävä:'<<id1<<''<<ch<<''<<yleensä<<'' n'';

palataid1;

}


intcb(inttunniste)

{

kustannus<<'takaisinsoittotoiminto'<<'' n'';

palatatunniste;

}


inttärkein()

{

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

hiiltyäei[] = 'ja';

mainFn(isä, cb);



palata 0;

}

Lähtö on:

soittotoiminto

päätoiminto: 1 ja 2

Päätoiminto tunnistetaan pääasiallisella Fn (): lla. Takaisinsoittotoiminnon tunnistaa cb (). Takaisinsoittotoiminto määritellään päätoiminnon ulkopuolella, mutta sitä kutsutaan varsinaisesti päätoiminnon sisällä.

Huomaa takaisinsoittotoiminnon ilmoitus parametrina päätoimintoilmoituksen parametriluettelossa. Takaisinsoittotoiminnon ilmoitus on int (*ptr) (int). Huomaa takaisinsoittotoiminnon lauseke, kuten funktion kutsu, päätoiminnon määritelmässä; kaikki argumentit soittotoiminnon kutsulle välitetään siellä. Tämän funktion kutsun lause on:



intyleensä= (*ptr)(id2);

Missä id2 on argumentti. ptr on osa parametria, osoitinta, joka linkitetään main () -funktion takaisinsoittotoiminnon viitteeseen.

Huomaa lauseke:

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

Päätoiminnossa (), joka yhdistää takaisinsoittotoiminnon ilmoituksen (ilman määritelmää) saman takaisinsoittotoiminnon määritelmän nimeen.

Päätoimintoa kutsutaan pääfunktiossa () seuraavasti:

mainFn(isä, cb);

Missä cha on merkkijono ja cb on takaisinsoittotoiminnon nimi ilman sen argumentteja.

Takaisinsoittotoiminnon synkroninen käyttäytyminen

Harkitse seuraavaa ohjelmaa:

#sisältää

käyttämällä nimiavaruustuntia;



mitätönmainFn(mitätön (*ptr)())

{

kustannus<<'päätehtävä'<<'' n'';

(*ptr)();

}


mitätöncb()

{

kustannus<<'takaisinsoittotoiminto'<<'' n'';

}


mitätönfn()

{

kustannus<<'nähnyt'<<'' n'';

}


inttärkein()

{

mitätön (*ptr)() = &cb;

mainFn(cb);

fn();



palata 0;

}

Lähtö on:

päätoiminto

soittotoiminto

nähty

Tässä on uusi toiminto. Kaikki uusi toiminto ei ole, on näyttää ulostulo, nähnyt. Main () -funktiossa kutsutaan pääfunktiota ja sitten uutta funktiota fn (). Tulos osoittaa, että päätoiminnon koodi suoritettiin, sitten takaisinsoittotoiminnon koodi ja lopuksi fn () -funktio. Tämä on synkronista (yksisäikeistä) käyttäytymistä.

Jos käyttäytyminen olisi asynkronista, kun kolme koodisegmenttiä kutsutaan järjestyksessä, ensimmäinen koodisegmentti voidaan suorittaa ja sen jälkeen suorittaa kolmas koodisegmentti ennen toisen koodisegmentin suorittamista.

Funktio, fn () voidaan kutsua päätoiminnon määritelmän sisältä, eikä pääfunktion () funktiosta, seuraavasti:

#sisältää

käyttämällä nimiavaruustuntia;



mitätönfn()

{

kustannus<<'nähnyt'<<'' n'';

}


mitätönmainFn(mitätön (*ptr)())

{

kustannus<<'päätehtävä'<<'' n'';

fn();

(*ptr)();

}


mitätöncb()

{

kustannus<<'takaisinsoittotoiminto'<<'' n'';

}


inttärkein()

{

mitätön (*ptr)() = &cb;

mainFn(cb);



palata 0;

}

Lähtö on:

päätoiminto

nähty

soittotoiminto

Tämä on asynkronisen käyttäytymisen jäljitelmä. Se ei ole asynkronista käyttäytymistä. Se on edelleen synkronista käyttäytymistä.

Myös päätoiminnon koodisegmentin ja takaisinsoittotoiminnon koodisegmentin suoritusjärjestys voidaan vaihtaa päätoiminnon määritelmässä. Seuraava ohjelma havainnollistaa tätä:

#sisältää

käyttämällä nimiavaruustuntia;



mitätönmainFn(mitätön (*ptr)())

{

(*ptr)();

kustannus<<'päätehtävä'<<'' n'';

}


mitätöncb()

{

kustannus<<'takaisinsoittotoiminto'<<'' n'';

}


mitätönfn()

{

kustannus<<'nähnyt'<<'' n'';

}


inttärkein()

{

mitätön (*ptr)() = &cb;

mainFn(cb);

fn();



palata 0;

}

Lähtö on nyt,

soittotoiminto

päätoiminto

nähty

Tämä on myös asynkronisen käyttäytymisen jäljitelmä. Se ei ole asynkronista käyttäytymistä. Se on edelleen synkronista käyttäytymistä. Todellinen asynkroninen käyttäytyminen voidaan saada, kuten seuraavassa osassa selitetään tai kirjaston kanssa, tulevaisuudessa.

Asynkroninen käyttäytyminen takaisinsoittotoiminnon kanssa

Perusasynkronisen takaisinsoittotoimintamallin pseudokoodi on:

tyyppinen lähtö;

tyyppi cb(tyyppinen lähtö)

{

// lausunnot

}


tyyppi mainFn(kirjoita tulo, kirjoita cb(tyyppinen lähtö))

{

// lausunnot

}

Huomaa tulo- ja lähtötietojen sijainnit pseudokoodin eri paikoissa. Takaisinsoittotoiminnon tulo on sen lähtö. Päätoiminnon parametrit ovat yleisen koodin syöttöparametri ja takaisinsoittotoiminnon parametri. Tässä mallissa voidaan suorittaa (kutsua) kolmas toiminto päätoiminnossa () ennen kuin takaisinsoittotoiminnon lähtö luetaan (edelleen pää () -toiminnossa). Seuraava koodi havainnollistaa tätä:

#sisältää

käyttämällä nimiavaruustuntia;

hiiltyä *lähtö;


mitätöncb(hiiltyäulos[])

{

lähtö=ulos;

}



mitätönmainFn(hiiltyätulo[],mitätön (*ptr)(hiiltyä[viisikymmentä]))

{

(*ptr)(tulo);

kustannus<<'päätehtävä'<<'' n'';

}


mitätönfn()

{

kustannus<<'nähnyt'<<'' n'';

}


inttärkein()

{

hiiltyätulo[] = 'takaisinsoittotoiminto';

mitätön (*ptr)(hiiltyä[]) = &cb;

mainFn(tulo, cb);

fn();

kustannus<<lähtö<<'' n'';



palata 0;

}

Ohjelman lähtö on:

päätoiminto

nähty

soittotoiminto

Tässä nimenomaisessa koodissa lähtö- ja tulopiste on sama peruspiste. Päätoiminnon () kolmannen toimintokutsun tulos on näytetty ennen soittotoiminnon tulosta. Takaisinsoittotoiminto suoritti, lopetti ja määritteli tuloksensa (arvon) muuttujalle, jolloin ohjelma voi jatkaa ilman häiriöitä. Päätoiminnossa () käytettiin soittotoiminnon lähtöä (luettiin ja näytettiin), kun sitä tarvittiin, mikä johti asynkroniseen käyttäytymiseen koko järjestelmässä.

Tämä on yksisäikeinen tapa saada takaisinsoittotoiminnon asynkroninen käyttäytyminen puhtaalla C ++: lla.

Tulevan kirjaston peruskäyttö

Asynkronisen soittotoimintamallin ajatuksena on, että päätoiminto palaa ennen kuin takaisinsoittotoiminto palaa. Tämä tehtiin epäsuorasti, tehokkaasti, yllä olevassa koodissa.

Huomaa yllä olevasta koodista, että takaisinsoittotoiminto vastaanottaa koodin pääsyötteen ja tuottaa koodin päälähdön. Tulevaisuuden C ++ -kirjastossa on toiminto nimeltä sync (). Ensimmäinen argumentti tälle toiminnolle on soittofunktion viite; toinen argumentti on tulo takaisinsoittotoimintoon. Synkronointi () -toiminto palaa odottamatta takaisinsoittotoiminnon suorittamista, mutta sallii soittotoiminnon päättymisen. Tämä tarjoaa asynkronisen käyttäytymisen. Kun takaisinsoittotoiminto jatkaa suoritustaan, koska sync () -toiminto on jo palannut, sen alla olevat lausumat suoritetaan edelleen. Tämä on kuin ihanteellinen asynkroninen käyttäytyminen.

Yllä oleva ohjelma on kirjoitettu uudelleen alla, ottaen huomioon tuleva kirjasto ja sen synkronointitoiminto:

#sisältää

#sisältää

#sisältää

käyttämällä nimiavaruustuntia;

tulevaisuudessa<merkkijono>lähtö;

merkkijono cb(merkkijono stri)

{

palatastri;

}



mitätönmainFn(merkkijonon syöttö)

{

lähtö=async(cb, syöttö);

kustannus<<'päätehtävä'<<'' n'';

}


mitätönfn()

{

kustannus<<'nähnyt'<<'' n'';

}


inttärkein()

{

merkkijonon syöttö=merkkijono('takaisinsoittotoiminto');

mainFn(tulo);

fn();

merkkijono ret=lähtö.saada(); // odottaa, että takaisinsoitto palaa tarvittaessa

kustannus<<oikein<<'' n'';



palata 0;

}

Synkronointi () -toiminto tallentaa lopuksi takaisinsoittotoiminnon tuloksen tulevaan objektiin. Odotettu lähtö voidaan saada pääfunktiossa () käyttämällä tulevan objektin get () jäsenfunktiota.

Johtopäätös

Takaisinsoittotoiminto on funktio, joka on argumentti, ei parametri, toisessa funktiossa. Takaisinsoittotoimintojärjestelmä tarvitsee päätoiminnon ja itse takaisinsoittotoiminnon. Takaisinsoittotoiminnon ilmoitus on osa päätoiminnon parametriluetteloa. Takaisinsoittotoiminnon määritelmä näkyy päätoiminnon funktiokutsussa (main ()). Takaisinsoittotoimintoa kutsutaan itse asiassa päätoiminnon määritelmän sisällä.

Takaisinsoittotoiminto ei välttämättä ole asynkroninen. Varmistaaksesi, että takaisinsoittotoiminto on asynkroninen, syötä koodin pääsyöttö ja soittotoiminnon tulo; tehdä koodin päälähtö, soittotoiminnon lähtö; tallentaa takaisinsoittotoiminnon tuotoksen muuttujaan tai tietorakenteeseen. Suorita päätoiminnossa () päätoiminnon kutsumisen jälkeen muut sovelluksen lausumat. Kun takaisinsoittotoiminnon lähtöä tarvitaan, käytä (lue ja näytä) sitä pää- () -toiminnossa siellä ja silloin.