C++

C++'da Geri Çağırma İşlevi

C++'da Geri Çağırma İşlevi

Geri arama işlevi, başka bir işlevde parametre değil, bağımsız değişken olan bir işlevdir. Diğer işlev asıl işlev olarak adlandırılabilir. Yani iki işlev söz konusudur: asıl işlev ve geri arama işlevinin kendisi. Ana işlevin parametre listesinde, atamasız nesne bildirimleri olduğu gibi, geri çağırma işlevinin tanımı olmadan bildirimi bulunur. Asıl işlev argümanlarla çağrılır (main() içinde). Asıl işlev çağrısındaki argümanlardan biri, geri arama işlevinin etkin tanımıdır. C++'da bu bağımsız değişken, geri arama işlevinin tanımına bir başvurudur; gerçek tanım değil. Geri arama işlevinin kendisi aslında asıl işlevin tanımı içinde çağrılır.

C++'daki temel geri çağırma işlevi, bir programda zaman uyumsuz davranışı garanti etmez.  Asenkron davranış, geri arama işlevi şemasının gerçek yararıdır. Asenkron geri çağırma işlevi şemasında, geri arama işlevinin sonucu elde edilmeden önce program için asıl işlevin sonucu alınmalıdır. Bunu C++'da yapmak mümkündür; ancak, C++, asenkron geri çağırma işlevi şemasının davranışını garanti etmek için gelecek adlı bir kitaplığa sahiptir.

Bu makale, temel geri arama işlevi şemasını açıklar. Birçoğu saf C ile++. Geri arama söz konusu olduğunda, gelecekteki kütüphanenin temel davranışı da açıklanmıştır. Bu makalenin anlaşılması için temel C++ bilgisi ve işaretçileri gereklidir.

Makale İçeriği

Temel Geri Çağırma İşlev Şeması

Bir geri arama işlevi şeması, bir ana işleve ve geri arama işlevinin kendisine ihtiyaç duyar. Geri arama işlevinin bildirimi, ana işlevin parametre listesinin bir parçasıdır. Geri arama işlevinin tanımı, asıl işlevin işlev çağrısında belirtilir. Geri arama işlevi aslında asıl işlevin tanımı içinde çağrılır. Aşağıdaki program bunu göstermektedir:

#Dahil etmek
ad alanı std kullanarak;
int anaparaFn(char ch[], int (*ptr)(int))

int id1 = 1;
int id2 = 2;
int idr = (*ptr)(id2);
cout<<"principal function: "<dönüş id1;

int cb(int kimliği)

cout<<"callback function"<<'\n';
dönüş kimliği;

int ana()

int (*ptr)(int) = &cb;
char cha[] = "ve";
anaparaFn(cha, cb);
0 döndür;

Çıktı:

geri arama işlevi
ana fonksiyon: 1 ve 2

Asıl işlev, PrincipalFn() ile tanımlanır. Geri arama işlevi cb() ile tanımlanır. Geri arama işlevi, asıl işlevin dışında tanımlanır, ancak aslında asıl işlev içinde çağrılır.

Ana işlev bildiriminin parametre listesinde bir parametre olarak geri çağırma işlevinin bildirimini not edin. Geri arama işlevinin bildirimi “int (*ptr)(int)” şeklindedir. Ana işlevin tanımındaki bir işlev çağrısı gibi geri arama işlevi ifadesini not edin; geri arama işlevi çağrısı için herhangi bir argüman oraya iletilir. Bu işlev çağrısının ifadesi:

int idr = (*ptr)(id2);

id2 bir argüman olduğunda. ptr, main() işlevindeki geri çağırma işlevinin referansına bağlanacak olan bir işaretçi olan parametrenin bir parçasıdır.

Şu ifadeye dikkat edin:

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

Geri arama işlevinin bildirimini (tanımsız) aynı geri arama işlevinin tanımının adına bağlayan main() işlevinde.

main() işlevinde ana işlev şu şekilde çağrılır:

anaparaFn(cha, cb);

Cha'nın bir dizge olduğu ve cb'nin herhangi bir argümanı olmadan geri çağırma işlevinin adı olduğu.

Geri Çağırma İşlevinin Eşzamanlı Davranışı

Aşağıdaki programı göz önünde bulundurun:

#Dahil etmek
ad alanı std kullanarak;
geçersiz anaparaFn(void (*ptr)())

cout<<"principal function"<<'\n';
(*ptr)();

geçersiz cb()

cout<<"callback function"<<'\n';

geçersiz fn()

cout<<"seen"<<'\n';

int ana()

geçersiz (*ptr)() = &cb;
anaparaFn(cb);
fn();
0 döndür;

Çıktı:

asıl işlev
geri arama işlevi
görüldü

Burada yeni bir fonksiyon var. Tüm yeni işlevin yaptığı, “görülen” çıktıyı görüntülemektir. main() işlevinde, asıl işlev çağrılır, ardından yeni işlev olan fn() çağrılır. Çıktı, ana işlev kodunun yürütüldüğünü, ardından geri çağırma işlevi için yürütüldüğünü ve son olarak fn() işlevi için yürütüldüğünü gösterir. Bu eşzamanlı (tek iş parçacıklı) davranıştır.

Asenkron davranış olsaydı, sırayla üç kod segmenti çağrıldığında, birinci kod segmenti yürütülebilir, ardından ikinci kod segmenti yürütülmeden önce üçüncü kod segmenti yürütülebilir.

Peki, fn() işlevi, main() işlevinin içinden değil, asıl işlevin tanımından aşağıdaki gibi çağrılabilir:

#Dahil etmek
ad alanı std kullanarak;
geçersiz fn()

cout<<"seen"<<'\n';

geçersiz anaparaFn(void (*ptr)())

cout<<"principal function"<<'\n';
fn();
(*ptr)();

geçersiz cb()

cout<<"callback function"<<'\n';

int ana()

geçersiz (*ptr)() = &cb;
anaparaFn(cb);
0 döndür;

Çıktı:

asıl işlev
görüldü
geri arama işlevi

Bu eşzamansız davranışın bir taklididir. Eşzamansız davranış değil. Hala senkronize davranış.

Ayrıca, asıl işlevin kod bölümünün yürütme sırası ve geri arama işlevinin kod bölümü, asıl işlevin tanımında yer değiştirebilir. Aşağıdaki program bunu göstermektedir:

#Dahil etmek
ad alanı std kullanarak;
 
geçersiz anaparaFn(void (*ptr)())

(*ptr)();
cout<<"principal function"<<'\n';

geçersiz cb()

cout<<"callback function"<<'\n';

geçersiz fn()

cout<<"seen"<<'\n';

int ana()

geçersiz (*ptr)() = &cb;
anaparaFn(cb);
fn();
0 döndür;

çıktı şimdi,

geri arama işlevi
asıl işlev
görüldü

Bu aynı zamanda asenkron davranışın bir taklididir. Eşzamansız davranış değil. Hala senkronize davranış. Gerçek asenkron davranış, bir sonraki bölümde açıklandığı gibi veya gelecekte kütüphane ile elde edilebilir.

Geri Çağırma İşlevli Eşzamansız Davranış

Temel eşzamansız geri arama işlevi şeması için sözde kod:

tip çıktı;
cb yazın (çıktı yazın)

//ifadeler

asılFn yazın(giriş yazın, cb yazın(çıktı yazın))

//ifadeler

Sözde kodun farklı yerlerindeki giriş ve çıkış verilerinin konumlarını not edin. Geri arama işlevinin girişi, çıkışıdır. Ana işlevin parametreleri, genel kod için giriş parametresi ve geri arama işlevi için parametredir. Bu şema ile, geri çağırma işlevinin çıktısı okunmadan önce (hala main() işlevinde) main() işlevinde üçüncü bir işlev yürütülebilir (çağrılır). Aşağıdaki kod bunu göstermektedir:

#Dahil etmek
ad alanı std kullanarak;
karakter * çıktısı;
void cb(char out[])

çıkış = çıkış;

geçersiz anaparaFn(char girdisi[], geçersiz (*ptr)(char[50]))

(*ptr)(giriş);
cout<<"principal function"<<'\n';

geçersiz fn()

cout<<"seen"<<'\n';

int ana()

char input[] = "geri arama işlevi";
void (*ptr)(char[]) = &cb;
anaparaFn(giriş, cb);
fn();
cout<0 döndür;

Programın çıktısı:

asıl işlev
görüldü
geri arama işlevi

Bu özel kodda, çıkış ve giriş verisi aynı veri olur. main() işlevindeki üçüncü işlev çağrısının sonucu, geri arama işlevinin sonucundan önce görüntülendi. Geri çağırma işlevi yürütüldü, tamamlandı ve sonucunu (değerini) değişkene, çıktıya atadı ve programın müdahalesi olmadan devam etmesine izin verdi. main() işlevinde, gerektiğinde geri çağırma işlevinin çıktısı kullanıldı (okundu ve görüntülendi), tüm şema için eşzamansız davranışa yol açtı.

Bu, saf C ile geri arama işlevi eşzamansız davranışı elde etmenin tek iş parçacıklı yoludur++.

Gelecekteki Kitaplığın temel kullanımı

Eşzamansız geri arama işlevi şemasının fikri, geri arama işlevi geri dönmeden önce asıl işlevin geri dönmesidir. Bu, yukarıdaki kodda dolaylı olarak, etkili bir şekilde yapıldı.

Yukarıdaki koddan, geri arama işlevinin kod için ana girdiyi aldığını ve kod için ana çıktıyı ürettiğini unutmayın. Gelecekteki C++ kitaplığı sync() adlı bir işleve sahiptir. Bu işlevin ilk argümanı geri arama işlevi başvurusudur; ikinci argüman, geri arama işlevinin girişidir. sync() işlevi, geri arama işlevinin yürütülmesinin tamamlanmasını beklemeden geri döner, ancak geri arama işlevinin tamamlanmasına izin verir. Bu asenkron davranış sağlar. Geri çağırma işlevi yürütülmeye devam ederken, sync() işlevi zaten döndüğü için aşağıdaki ifadeler yürütülmeye devam eder. Bu ideal eşzamansız davranış gibidir.

Yukarıdaki program, gelecekteki kitaplık ve sync() işlevi dikkate alınarak aşağıda yeniden yazılmıştır:

#Dahil etmek
#Dahil etmek
#Dahil etmek
ad alanı std kullanarak;
gelecek çıktı;
string cb(string stri)

dönüş şeridi;

geçersiz anaparaFn(dize girişi)

çıktı = zaman uyumsuz(cb, girdi);
cout<<"principal function"<<'\n';

geçersiz fn()

cout<<"seen"<<'\n';

int ana()

string girdi = string("geri arama fonksiyonu");
anaparaFn(giriş);
fn();
string ret = çıktı.almak(); //gerekirse geri aramanın dönmesini bekler
cout<0 döndür;

sync() işlevi sonunda geri çağırma işlevinin çıktısını gelecekteki nesneye depolar. Beklenen çıktı, main() işlevinde, gelecekteki nesnenin get() üye işlevi kullanılarak elde edilebilir.

Sonuç

Geri arama işlevi, başka bir işlevde parametre değil, bağımsız değişken olan bir işlevdir. Bir geri arama işlevi şeması, bir ana işleve ve geri arama işlevinin kendisine ihtiyaç duyar. Geri arama işlevinin bildirimi, ana işlevin parametre listesinin bir parçasıdır. Geri arama işlevinin tanımı, ana işlevin işlev çağrısında belirtilir (ana() içinde). Geri arama işlevi aslında asıl işlevin tanımı içinde çağrılır.

Bir geri arama işlevi şeması mutlaka eşzamansız değildir. Geri arama fonksiyon şemasının asenkron olduğundan emin olmak için, kodun ana girişini, geri arama fonksiyonunun girişini yapın; kodun ana çıktısını, geri arama işlevinin çıktısını yapın; geri çağırma işlevinin çıktısını bir değişken veya veri yapısında saklayın. main() işlevinde, asıl işlevi çağırdıktan sonra, uygulamanın diğer deyimlerini yürütün. Geri arama işlevinin çıktısına ihtiyaç duyulduğunda, ana () işlevinde, onu orada kullanın (okuyun ve görüntüleyin) ve sonra.

How to Show FPS Counter in Linux Games
Linux gaming got a major push when Valve announced Linux support for Steam client and their games in 2012. Since then, many AAA and indie games have m...
How to download and Play Sid Meier's Civilization VI on Linux
Introduction to the game Civilization 6 is a modern take on the classic concept introduced in the series of the Age of Empires games. The idea was fai...
How to Install and Play Doom on Linux
Introduction to Doom The Doom Series originated in the 90s after the release of the original Doom. It was an instant hit and from that time onwards th...