Callback Function sa C ++

Callback Function C



Ang isang function ng callback ay isang function, na kung saan ay isang argument, hindi isang parameter, sa isa pang pagpapaandar. Ang iba pang pag-andar ay maaaring tawaging pangunahing pagpapaandar. Kaya't kasangkot ang dalawang pagpapaandar: ang pangunahing pagpapaandar at ang function ng callback mismo. Sa listahan ng parameter ng pangunahing pagpapaandar, ang deklarasyon ng pagpapaandar ng callback nang walang kahulugan nito ay naroroon, tulad ng mga deklarasyon ng object nang walang pagtatalaga ay naroroon. Ang punong tungkulin ay tinatawag na may mga argumento (sa pangunahing ()). Ang isa sa mga argumento sa punong tawag sa pagpapaandar ay ang mabisang kahulugan ng pagpapaandar ng callback. Sa C ++, ang argument na ito ay isang sanggunian sa kahulugan ng pagpapaandar ng callback; hindi ito ang tunay na kahulugan. Ang callback function mismo ay talagang tinawag sa loob ng kahulugan ng pangunahing pagpapaandar.

Ang pangunahing pag-andar ng callback sa C ++ ay hindi ginagarantiyahan ang asynchronous na pag-uugali sa isang programa. Ang hindi pag-ugnay na pag-uugali ay ang tunay na pakinabang ng scheme ng pagpapaandar ng callback. Sa iskema ng pagpapaandar na hindi asynchronous na callback, ang resulta ng pangunahing pagpapaandar ay dapat makuha para sa programa bago makuha ang resulta ng pag-andar ng callback. Posibleng gawin ito sa C ++; gayunpaman, ang C ++ ay may isang library na tinatawag na hinaharap upang magarantiyahan ang pag-uugali ng asynchronous callback function scheme.







Ipinapaliwanag ng artikulong ito ang pangunahing scheme ng pagpapaandar ng callback. Marami dito ay may purong C ++. Hinggil sa pag-aalala sa callback, ipinaliwanag din ang pangunahing pag-uugali ng aklatan sa hinaharap. Ang pangunahing kaalaman sa C ++ at ang mga tagubilin nito ay kinakailangan para sa pag-unawa sa artikulong ito.



Nilalaman ng Artikulo

Pangunahing Skema ng Pag-andar ng Callback

Ang isang scheme ng pagpapaandar ng callback ay nangangailangan ng isang pangunahing pagpapaandar, at ang function ng callback mismo. Ang pagdeklara ng pagpapaandar ng callback ay bahagi ng listahan ng parameter ng pangunahing pagpapaandar. Ang kahulugan ng pagpapaandar ng callback ay ipinahiwatig sa pag-andar ng tawag sa punong-guro na pagpapaandar. Ang pag-andar ng callback ay talagang tinawag sa loob ng kahulugan ng pangunahing pagpapaandar. Inilalarawan ito ng sumusunod na programa:



# isama

gamit namespaceoras;



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

{

intid1= 1;

intid2= 2;

intkadalasan= (*ptr)(id2);

gastos<<'pangunahing pagpapaandar:'<<id1<<'<<ch<<'<<kadalasan<<' n';

bumalik kaid1;

}


intcb(intiden)

{

gastos<<'function ng callback'<<' n';

bumalik kaiden;

}


intpangunahing()

{

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

charhindi[] = 'at';

mainFn(ama, cb);



bumalik ka 0;

}

Ang output ay:





pagpapaandar ng callback

pangunahing pagpapaandar: 1 at 2

Ang pangunahing pag-andar ay kinilala ng prinsipFn (). Ang pag-andar ng callback ay kinilala ng cb (). Ang pagpapaandar ng callback ay tinukoy sa labas ng pangunahing pagpapaandar ngunit aktwal na tinawag sa loob ng pangunahing pagpapaandar.

Tandaan ang pagdeklara ng pagpapaandar ng callback bilang isang parameter sa listahan ng parameter ng pangunahing pagdeklara ng pangunahing pag-andar. Ang pagdeklara ng pagpapaandar ng callback ay int (* ptr) (int). Tandaan ang ekspresyon ng pagpapaandar ng callback, tulad ng isang function call, sa kahulugan ng pangunahing pagpapaandar; ang anumang pagtatalo para sa callback function na tawag ay naipasa doon. Ang pahayag para sa tawag na ito sa pagpapaandar ay:



intkadalasan= (*ptr)(id2);

Kung saan ang id2 ay isang pagtatalo. Ang ptr ay bahagi ng parameter, isang pointer, na mai-link sa sanggunian ng pagpapaandar ng callback sa pangunahing () pagpapaandar.

Tandaan ang expression:

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

Sa pangunahing () pagpapaandar, na nag-uugnay sa deklarasyon (nang walang kahulugan) ng pagpapaandar ng callback sa pangalan ng kahulugan ng parehong function ng callback.

Ang pangunahing pagpapaandar ay tinatawag na, sa pangunahing () pagpapaandar, bilang:

mainFn(ama, cb);

Kung saan ang cha ay isang string at cb ang pangalan ng callback function nang walang alinmang argumento nito.

Kasabay na Pag-uugali ng Pag-andar ng Callback

Isaalang-alang ang sumusunod na programa:

# isama

gamit namespaceoras;



walang bisamainFn(walang bisa (*ptr)())

{

gastos<<'pangunahing pagpapaandar'<<' n';

(*ptr)();

}


walang bisacb()

{

gastos<<'function ng callback'<<' n';

}


walang bisafn()

{

gastos<<'nakita'<<' n';

}


intpangunahing()

{

walang bisa (*ptr)() = &cb;

mainFn(cb);

fn();



bumalik ka 0;

}

Ang output ay:

pangunahing pagpapaandar

pagpapaandar ng callback

nakita

Mayroong isang bagong pagpapaandar dito. Ang lahat ng ginagawa ng bagong pagpapaandar, ay upang ipakita ang output, nakikita. Sa pangunahing () pag-andar, ang pangunahing pagpapaandar ay tinawag, pagkatapos ang bagong pagpapaandar, fn () ay tinawag. Ipinapakita ng output na ang code para sa pangunahing pagpapaandar ay naisakatuparan, pagkatapos na para sa function ng callback ay naisakatuparan, at sa wakas na para sa fn () na pagpapaandar ay naisakatuparan. Ito ay magkasabay (solong-sinulid) na pag-uugali.

Kung ito ay walang pag-uugali na pag-uugali, kapag ang tatlong mga segment ng code ay tinawag sa pagkakasunud-sunod, ang unang segment ng code ay maaaring maipatupad, na sinusundan ng pagpapatupad ng ikatlong bahagi ng code, bago ipatupad ang pangalawang segment ng code.

Kaya, ang pagpapaandar, fn () ay maaaring tawagan mula sa loob ng kahulugan ng pangunahing pagpapaandar, sa halip na mula sa loob ng pangunahing () pagpapaandar, tulad ng sumusunod:

# isama

gamit namespaceoras;



walang bisafn()

{

gastos<<'nakita'<<' n';

}


walang bisamainFn(walang bisa (*ptr)())

{

gastos<<'pangunahing pagpapaandar'<<' n';

fn();

(*ptr)();

}


walang bisacb()

{

gastos<<'function ng callback'<<' n';

}


intpangunahing()

{

walang bisa (*ptr)() = &cb;

mainFn(cb);



bumalik ka 0;

}

Ang output ay:

pangunahing pagpapaandar

nakita

pagpapaandar ng callback

Ito ay isang panggagaya ng asynchronous na pag-uugali. Hindi ito asynchronous na pag-uugali. Kasabay pa rin nitong pag-uugali.

Gayundin, ang pagkakasunud-sunod ng pagpapatupad ng segment ng code ng pangunahing pagpapaandar at ang segment ng code ng pag-andar ng callback ay maaaring mapalitan sa kahulugan ng pangunahing pagpapaandar. Inilalarawan ito ng sumusunod na programa:

# isama

gamit namespaceoras;



walang bisamainFn(walang bisa (*ptr)())

{

(*ptr)();

gastos<<'pangunahing pagpapaandar'<<' n';

}


walang bisacb()

{

gastos<<'function ng callback'<<' n';

}


walang bisafn()

{

gastos<<'nakita'<<' n';

}


intpangunahing()

{

walang bisa (*ptr)() = &cb;

mainFn(cb);

fn();



bumalik ka 0;

}

Ang output ay ngayon,

pagpapaandar ng callback

pangunahing pagpapaandar

nakita

Ito rin ay isang pekeng ng asynchronous na pag-uugali. Hindi ito asynchronous na pag-uugali. Kasabay pa rin nitong pag-uugali. Ang tunay na pag-uugali na hindi magkakasabay ay maaaring makuha tulad ng ipinaliwanag sa susunod na seksyon o sa silid-aklatan, sa hinaharap.

Hindi magkakasabay na Pag-uugali na may Callback Function

Ang pseudo-code para sa pangunahing asynchronous callback function scheme ay:

uri ng output;

uri ng cb(uri ng output)

{

// pahayag

}


uri ng punong guroFn(uri ng input, uri ng cb(uri ng output))

{

// pahayag

}

Tandaan ang mga posisyon ng data ng pag-input at output sa iba't ibang mga lugar ng pseudo-code. Ang input ng pagpapaandar ng callback ay ang output nito. Ang mga parameter ng pangunahing pagpapaandar ay ang input parameter para sa pangkalahatang code at ang parameter para sa pagpapaandar ng callback. Sa ganitong pamamaraan, ang isang pangatlong pagpapaandar ay maaaring maipatupad (tinatawag) sa pangunahing () pagpapaandar bago mabasa ang output ng pagpapaandar ng callback (nasa pangunahing () pagpapaandar pa rin). Ang sumusunod na code ay naglalarawan nito:

# isama

gamit namespaceoras;

char *output;


walang bisacb(charpalabas[])

{

output=palabas;

}



walang bisamainFn(charinput[],walang bisa (*ptr)(char[limampu]))

{

(*ptr)(input);

gastos<<'pangunahing pagpapaandar'<<' n';

}


walang bisafn()

{

gastos<<'nakita'<<' n';

}


intpangunahing()

{

charinput[] = 'function ng callback';

walang bisa (*ptr)(char[]) = &cb;

mainFn(input, cb);

fn();

gastos<<output<<' n';



bumalik ka 0;

}

Ang output ng programa ay:

pangunahing pagpapaandar

nakita

pagpapaandar ng callback

Sa partikular na code na ito, ang output at input datum ay magkakaroon ng parehong datum. Ang resulta ng pangatlong function na tawag sa pangunahing () pagpapaandar ay ipinakita bago ang resulta ng pagpapaandar ng callback. Ang callback function ay naisakatuparan, natapos, at naitalaga ang resulta nito (halaga) sa variable, output, na pinapayagan ang programa na magpatuloy nang walang panghihimasok nito. Sa pangunahing () pag-andar, ang output ng pag-andar ng callback ay ginamit (basahin at ipakita) kung kinakailangan, na humahantong sa hindi magkakasamang pag-uugali para sa buong pamamaraan.

Ito ang nag-iisang sinulid na paraan upang makakuha ng pag-andar ng callback na asynchronous na pag-uugali na may purong C ++.

Pangunahing paggamit ng hinaharap na Library

Ang ideya ng asynchronous callback function scheme ay ang prinsipal na pagpapaandar ay bumalik bago bumalik ang pagpapaandar ng callback. Ginawa ito nang hindi direkta, mabisa, sa itaas na code.

Tandaan mula sa itaas na code na ang function ng callback ay tumatanggap ng pangunahing input para sa code at gumagawa ng pangunahing output para sa code. Ang C ++ library, sa hinaharap, ay may isang function na tinatawag na sync (). Ang unang argumento sa pagpapaandar na ito ay ang sanggunian sa pagpapaandar ng callback; ang pangalawang argument ay ang input sa pagpapaandar ng callback. Ang function na pag-sync () ay bumalik nang hindi naghihintay para sa pagpapatupad ng function ng callback upang makumpleto ngunit pinapayagan ang callback function na makumpleto. Nagbibigay ito ng hindi kasabay na pag-uugali. Habang ang function ng callback ay patuloy na isinasagawa, dahil ang function na pag-sync () ay bumalik na, ang mga pahayag sa ibaba nito ay patuloy na isinasagawa. Ito ay tulad ng perpektong asynchronous na pag-uugali.

Ang program sa itaas ay muling nasulat sa ibaba, isinasaalang-alang, ang hinaharap na library at ang pag-andar nito () na pag-andar:

# isama

# isama

# isama

gamit namespaceoras;

hinaharap<lubid>output;

string cb(string stri)

{

bumalik kastri;

}



walang bisamainFn(input ng string)

{

output=async(cb, input);

gastos<<'pangunahing pagpapaandar'<<' n';

}


walang bisafn()

{

gastos<<'nakita'<<' n';

}


intpangunahing()

{

input ng string=lubid('function ng callback');

mainFn(input);

fn();

string ret=outputkumuha ka(); // naghihintay para sa callback na bumalik kung kinakailangan

gastos<<tama<<' n';



bumalik ka 0;

}

Ang pag-andar ng sync () sa wakas ay nag-iimbak ng output ng function ng callback sa hinaharap na bagay. Ang inaasahang output ay maaaring makuha sa pangunahing () pagpapaandar, gamit ang pag-andar ng miyembro na makakuha ng) ng hinaharap na bagay.

Konklusyon

Ang isang function ng callback ay isang function, na kung saan ay isang argument, hindi isang parameter, sa isa pang pagpapaandar. Ang isang scheme ng pagpapaandar ng callback ay nangangailangan ng isang pangunahing pagpapaandar, at ang function ng callback mismo. Ang pagdeklara ng pagpapaandar ng callback ay bahagi ng listahan ng parameter ng pangunahing pagpapaandar. Ang kahulugan ng pagpapaandar ng callback ay ipinahiwatig sa pag-andar ng tawag ng punong-guro na pagpapaandar (sa pangunahing ()). Ang pag-andar ng callback ay talagang tinawag sa loob ng kahulugan ng pangunahing pagpapaandar.

Ang isang scheme ng pag-andar ng callback ay hindi kinakailangang asynchronous. Upang matiyak na ang callback function scheme ay hindi magkakasabay, gawin ang pangunahing input sa code, ang input sa function ng callback; gawin ang pangunahing output ng code, ang output ng pag-andar ng callback; itabi ang output ng function ng callback sa isang variable o istraktura ng data. Sa pangunahing () pag-andar, pagkatapos ng pagtawag sa pangunahing pagpapaandar, magpatupad ng iba pang mga pahayag ng aplikasyon. Kapag kinakailangan ang output ng pag-andar ng callback, sa pangunahing () pagpapaandar, gamitin ito (basahin at ipakita) doon at pagkatapos.