[Megoldva] Mire való a callback függvény?

Fórumok

Üdv!

Egy ideje már keresem a neten hogy milyen szituációkban lehet alkalmazni a callback-et. Amit találtam:

Rendezésnél ha többféle típusú adaton kell rendezést írni elég lenne a template, de ha az adat típusa megkövetel kis módosítást, akkor a callbak-et hozták fel példának. Átadom a rendező függvénynek az adat tömböt és az összehasonlító callback függvényt. ( Adatok például lehetnek számok vagy struct-ok és máris máshogy kell összehasonlítani őket.) A problémám az hogy nem tűnik bolondbiztosnak. Az adatok mellé rossz callback függvényt adhatok meg.

De... mivel most c++ tanulok, felvetődött bennem hogy lehetne-e kiváltani oop technikával? Például ha készítek az adatoknak burkoló osztályt, amiből származtatom a konkrét adat típushoz kapcsolódó osztályt. Ebben felülírom az == operátort. Ekkor összehasonlításkor MINDIG működik az == operátor (bármilyen adatról lenne szó), tehát a rendező algoritmus is ugyanaz lesz, mindig automatikusan az adatnak megfelelő komparálást végző operátor hívódna meg bolondbiztosan.

Másik eset amit találtam az interneten az a jelzés (bocs, magyarul nem jut eszembe a megfelelő terminológia, notification.) Abban a dszituációkban használhatom, ha elindítok egy folyamatot, akkor átadok egy callback függvényt amit a folyamat felhasználhat jelzésre. Jelezheti a szál indítónak hogy végzett a feladattal pl.

Erre a feladatra callback helyett a különféle framework-ök szolgáltatásait találtam pl.: qt esetén a signal – slot kommunikációt.

Nem callback ellenes vagyok, csak szeretném megtudni milyen helyzetekben használnak callback-et, illetve van-e alternatívája.

Köszi

Hozzászólások

1. Alternatíva MINDIG van.
2. Az első megoldásod ugyan működhet, de semmivel sem "bolondbiztosabb" a saját operator==-t átadni, mint egy összehasonlító függvényt. A rendezés ugye alapból a less-t használja, ami alapból az "operator<"-t hívja meg. Te adhatsz neki bármilyen összehasonlítást, ami két olyan dolgot átvesz és bool-t ad vissza. Az OOP-s megoldás két szempontból alacsonyabbrendű: sok vele a matatás, leszármazás kell hozzá, és sokszor nem férsz hozzá az osztályhoz írásra, nem tudod utólag belemódosítani, hogy jajjdemégeztazinterfésztvalósítsameg, főleg ha beépített típus, azokhoz végképp nem férsz hozzá, ráadásul ha mondjuk egyszer így, máskor úgy szeretnéd összehasonlítani, akkor megint meg vagy lőve a te megoldásoddal, márpedig ez nem elvetemült ötlet; másrészt hatékonysági kérdés: ha létrehozol egy összehasonlító osztályt, és azt adod oda, azt a fordító simán inlineolja, de legrosszabb esetben egy függvényhívás, a te megoldásod pedig mindenképp dinamikus függvényhívás, azaz vtable meg minden.
3. A Qt megoldása is csak callback, ha megnézed: megtörténik valami, meghívódik egy függvény. Erre a szituációra (aszinkron visszajelzés) ez az általános megoldás.
----
Hülye pelikán

Szia!

Alapvetően a callbacket értelmezhetjük kicsit szabadabban, azaz, hogy bármilyen olyan módszer, amikor egy meghívott függvény egy olyan függvényt hív meg, amit a hívó fél definiált. Így akkor ebbe a definícióba belefér pl a Javaban lévő Listener interface-ek is callback valamiféle megvalósításának, de alapvetően a C#-ban lévő delegate-ek is igazából callbackek. Egyébként alapvetően akkor van ilyenre szükség, ha egy osztály úgy van megvalósítva, hogy egy bizonyos esetben valamit csinálnia kell, amit a példányosításkor mondunk meg, hogy mi legyen. A legtipikusabb példa erre a GUI események kezelése (pl. gombnyomás). Szóval attól még, hogy nem dobálózunk függvény pointerekkel összevissza manapság(főleg mert a legtöbb modern nyelvben nem is lehet), valójában sokszor callbacket használunk.

De mondok neked egy másik példát, ahol callbacket használtam a közelmúltban, és ez volt az egyetlen lehetséges megoldás. Arról volt szó, hogy van egy C++ program, ami C#-ban megírt modulokban levő algoritmusokat hívogat meg COM hívások segítségével. Namármost mivel egy-egy algoritmus sokáig tart, ezért vissza kell küldeni progress információt a C++ programnak, hogy tudja, hogy hol jár, és mivel a COM interface elég alacsony szintű (tekintve hogy elméletileg független a használt nyelvtől), ezért ezt úgy oldottam meg, hogy átadok egy interface pointert a C# modulnak, és progress információt annak az egyik függvényének a meghívásával tud visszaadni.

A callback ebben az esetben pl. kimondottan rugalmasabb ha egy adatot több szempont alapján is rendezni akarsz. (pl. személyeket név és életkor és vagyoni helyzet stb... alapján )

Általában is sokszor növelheti a rugalmasságot a függvényparaméterek használata: érdemes megismerkedni olyan (funkcionális, vagy funkcionális elemeket tartalmazó) nyelvekkel amik ezt maximálisan igyekeznek kihasználni...

Köszönöm a példákat! Így már tisztább. :)