C ++

Fungsi Panggilan Balik dalam C ++

Fungsi Panggilan Balik dalam C ++

Fungsi panggilan balik adalah fungsi, yang merupakan argumen, bukan parameter, dalam fungsi lain. Fungsi lain boleh dipanggil fungsi utama. Oleh itu, dua fungsi terlibat: fungsi utama dan fungsi panggilan balik itu sendiri. Dalam senarai parameter fungsi utama, deklarasi fungsi panggilan balik tanpa definisinya ada, sama seperti pernyataan objek tanpa penugasan yang ada. Fungsi utama dipanggil dengan argumen (dalam utama ()). Salah satu argumen dalam fungsi panggilan utama adalah definisi berkesan fungsi panggilan balik. Dalam C ++, argumen ini merujuk kepada definisi fungsi panggilan balik; itu bukan definisi sebenarnya. Fungsi panggil balik itu sendiri sebenarnya disebut dalam definisi fungsi utama.

Fungsi panggilan balik asas dalam C ++ tidak menjamin tingkah laku tidak segerak dalam program.  Tingkah laku tak segerak adalah faedah sebenar skema fungsi panggilan balik. Dalam skema fungsi panggilan balik tak segerak, hasil fungsi utama harus diperoleh untuk program sebelum hasil fungsi panggilan balik diperoleh. Ada kemungkinan untuk melakukan ini di C ++; namun, C ++ mempunyai perpustakaan yang disebut masa depan untuk menjamin tingkah laku skema fungsi panggilan balik tak segerak.

Artikel ini menerangkan skema fungsi panggilan balik asas. Sebilangan besar dengan C tulen++. Mengenai panggilan balik, tingkah laku asas perpustakaan masa depan juga dijelaskan. Pengetahuan asas mengenai C ++ dan petunjuknya diperlukan untuk pemahaman artikel ini.

Kandungan Artikel

Skim Fungsi Panggilan Balik Asas

Skema fungsi panggilan balik memerlukan fungsi utama, dan fungsi panggilan balik itu sendiri. Pengisytiharan fungsi panggilan balik adalah sebahagian daripada senarai parameter fungsi utama. Definisi fungsi panggilan balik ditunjukkan dalam fungsi panggilan fungsi utama. Fungsi panggil balik sebenarnya dipanggil dalam definisi fungsi utama. Program berikut menggambarkan ini:

#sertakan
menggunakan ruang nama std;
int PrincipalFn (char ch [], int (* ptr) (int))

int id1 = 1;
int id2 = 2;
int idr = (* ptr) (id2);
cout<<"principal function: "<mengembalikan id1;

int cb (int iden)

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

int utama ()

int (* ptr) (int) = &cb;
char cha [] = "dan";
prinsipalFn (cha, cb);
pulangan 0;

Keluarannya adalah:

fungsi panggilan balik
fungsi utama: 1 dan 2

Fungsi utama dikenal pasti oleh principalFn (). Fungsi panggil balik dikenal pasti oleh cb (). Fungsi panggil balik didefinisikan di luar fungsi utama tetapi sebenarnya dipanggil dalam fungsi utama.

Perhatikan deklarasi fungsi panggilan balik sebagai parameter dalam senarai parameter deklarasi fungsi utama. Pengisytiharan fungsi panggilan balik adalah "int (* ptr) (int)". Perhatikan ungkapan fungsi panggilan balik, seperti fungsi panggilan, dalam definisi fungsi utama; sebarang hujah untuk panggilan fungsi panggilan balik disampaikan di sana. Pernyataan untuk panggilan fungsi ini adalah:

int idr = (* ptr) (id2);

Di mana id2 adalah hujah. ptr adalah bagian dari parameter, penunjuk, yang akan dihubungkan dengan rujukan fungsi panggilan balik dalam fungsi utama ().

Perhatikan ungkapan:

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

Dalam fungsi utama (), yang menghubungkan pengisytiharan (tanpa definisi) fungsi panggilan balik ke nama definisi fungsi panggilan balik yang sama.

Fungsi utama dipanggil, dalam fungsi utama (), sebagai:

prinsipalFn (cha, cb);

Di mana cha adalah rentetan dan cb adalah nama fungsi panggilan balik tanpa ada argumennya.

Tingkah Laku Fungsi Panggilan Balik

Pertimbangkan program berikut:

#sertakan
menggunakan ruang nama std;
void prinsipal Fn (void (* ptr) ())

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

batal cb ()

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

batal fn ()

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

int utama ()

tidak sah (* ptr) () = &cb;
prinsipalFn (cb);
fn ();
pulangan 0;

Keluarannya adalah:

fungsi utama
fungsi panggilan balik
dilihat

Terdapat fungsi baru di sini. Semua fungsi baru yang dilakukan adalah untuk menampilkan output, "dilihat". Dalam fungsi utama (), fungsi utama dipanggil, kemudian fungsi baru, fn () dipanggil. Output menunjukkan bahawa kod untuk fungsi utama dieksekusi, kemudian untuk fungsi panggil balik dijalankan, dan akhirnya untuk fungsi fn () dijalankan. Ini adalah tingkah laku segerak (utas tunggal).

Sekiranya itu adalah tingkah laku asinkron, apabila tiga segmen kod dipanggil dalam urutan, segmen kod pertama dapat dijalankan, diikuti oleh pelaksanaan segmen kod ketiga, sebelum segmen kod kedua dijalankan.

Nah, fungsi, fn () dapat dipanggil dari dalam definisi fungsi utama, bukan dari dalam fungsi utama (), seperti berikut:

#sertakan
menggunakan ruang nama std;
batal fn ()

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

void prinsipal Fn (void (* ptr) ())

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

batal cb ()

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

int utama ()

tidak sah (* ptr) () = &cb;
prinsipalFn (cb);
pulangan 0;

Keluarannya adalah:

fungsi utama
dilihat
fungsi panggilan balik

Ini adalah tiruan daripada tingkah laku tidak segerak. Ia bukan tingkah laku tidak segerak. Itu masih tingkah laku segerak.

Juga, urutan pelaksanaan segmen kod fungsi utama dan segmen kod fungsi panggilan balik dapat ditukar dalam definisi fungsi utama. Program berikut menggambarkan ini:

#sertakan
menggunakan ruang nama std;
 
void prinsipal Fn (void (* ptr) ())

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

batal cb ()

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

batal fn ()

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

int utama ()

tidak sah (* ptr) () = &cb;
prinsipalFn (cb);
fn ();
pulangan 0;

Keluarannya sekarang,

fungsi panggilan balik
fungsi utama
dilihat

Ini juga merupakan tiruan daripada tingkah laku tak segerak. Ia bukan tingkah laku tidak segerak. Itu masih tingkah laku segerak. Tingkah laku asinkron yang benar dapat diperoleh seperti yang dijelaskan di bahagian seterusnya atau dengan perpustakaan, di masa depan.

Tingkah Laku tak segerak dengan Fungsi Panggilan Balik

Kod pseudo untuk skema fungsi panggilan balik asinkron asas adalah:

keluarkan jenis;
taip cb (jenis output)

// pernyataan

taip prinsipal Fn (input type, type cb (type output))

// pernyataan

Perhatikan kedudukan data input dan output di tempat berlainan kod pseudo. Input fungsi panggilan balik adalah outputnya. Parameter fungsi utama adalah parameter input untuk kod umum dan parameter untuk fungsi panggilan balik. Dengan skema ini, fungsi ketiga dapat dijalankan (disebut) dalam fungsi utama () sebelum output fungsi panggilan balik dibaca (masih dalam fungsi utama ()). Kod berikut menggambarkan ini:

#sertakan
menggunakan ruang nama std;
output char *;
batal cb (habiskan [])

output = keluar;

void prinsipal Fn (char char [], void (* ptr) (char [50]))

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

batal fn ()

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

int utama ()

input char [] = "fungsi panggilan balik";
batal (* ptr) (char []) = &cb;
prinsipalFn (input, cb);
fn ();
cout<pulangan 0;

Output program adalah:

fungsi utama
dilihat
fungsi panggilan balik

Dalam kod ini, datum output dan input kebetulan adalah datum yang sama. Hasil panggilan fungsi ketiga dalam fungsi utama () telah ditampilkan sebelum hasil fungsi panggilan balik. Fungsi panggil balik dilaksanakan, selesai, dan memberikan hasilnya (nilai) ke pemboleh ubah, output, yang membolehkan program diteruskan tanpa gangguannya. Dalam fungsi utama (), output fungsi panggilan balik digunakan (dibaca dan ditampilkan) ketika diperlukan, yang membawa kepada tingkah laku asinkron untuk keseluruhan skema.

Ini adalah kaedah utas tunggal untuk mendapatkan fungsi panggilan balik tingkah laku tak segerak dengan C tulen++.

Penggunaan asas Perpustakaan masa depan

Idea skema fungsi panggilan balik tidak segerak ialah fungsi utama kembali sebelum fungsi panggilan balik kembali. Ini dilakukan secara tidak langsung, berkesan, dalam kod di atas.

Perhatikan dari kod di atas bahawa fungsi panggilan balik menerima input utama untuk kod dan menghasilkan output utama untuk kod tersebut. Perpustakaan C ++, di masa depan, mempunyai fungsi yang disebut sync (). Argumen pertama untuk fungsi ini adalah rujukan fungsi panggilan balik; argumen kedua adalah input untuk fungsi panggilan balik. Fungsi sync () kembali tanpa menunggu pelaksanaan fungsi callback selesai tetapi membolehkan fungsi callback selesai. Ini memberikan tingkah laku tidak segerak. Walaupun fungsi panggilan balik terus dijalankan, kerana fungsi sinkronisasi () sudah kembali, pernyataan di bawahnya terus dilaksanakan. Ini seperti tingkah laku tak segerak yang ideal.

Program di atas telah ditulis semula di bawah, dengan mempertimbangkan, perpustakaan masa depan dan fungsi penyegerakannya ():

#sertakan
#sertakan
#sertakan
menggunakan ruang nama std;
masa depan pengeluaran;
tali cb (rentetan rentetan)

kembali mengejar;

membatalkan prinsipal Fn (input rentetan)

output = async (cb, input);
cout<<"principal function"<<'\n';

batal fn ()

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

int utama ()

string input = string ("fungsi panggilan balik");
prinsipalFn (input);
fn ();
rentetan = output.dapatkan (); // menunggu panggilan balik kembali jika perlu
cout<pulangan 0;

Fungsi sync () akhirnya menyimpan output fungsi callback ke objek masa depan. Output yang diharapkan dapat diperoleh dalam fungsi utama (), menggunakan fungsi anggota get () dari objek masa depan.

Kesimpulannya

Fungsi panggilan balik adalah fungsi, yang merupakan argumen, bukan parameter, dalam fungsi lain. Skema fungsi panggilan balik memerlukan fungsi utama, dan fungsi panggilan balik itu sendiri. Pengisytiharan fungsi panggilan balik adalah sebahagian daripada senarai parameter fungsi utama. Definisi fungsi panggilan balik ditunjukkan dalam fungsi panggilan fungsi utama (dalam utama ()). Fungsi panggil balik sebenarnya dipanggil dalam definisi fungsi utama.

Skema fungsi panggilan balik tidak semestinya segerak. Untuk memastikan bahawa skema fungsi panggilan balik tidak segerak, buat input utama ke kod, input ke fungsi panggilan balik; membuat output utama kod, output fungsi panggilan balik; menyimpan output fungsi panggilan balik dalam pemboleh ubah atau struktur data. Dalam fungsi utama (), setelah memanggil fungsi utama, jalankan pernyataan aplikasi yang lain. Apabila output fungsi panggilan balik diperlukan, dalam fungsi utama (), gunakan (baca dan paparkan) di sana dan kemudian.

Cara Memasang League Of Legends di Ubuntu 14.04
Sekiranya anda peminat League of Legends, maka ini adalah peluang bagi anda untuk menguji menjalankan League of Legends. Perhatikan bahawa LOL disokon...
Pasang permainan Strategi OpenRA terkini di Ubuntu Linux
OpenRA adalah mesin permainan Strategi Masa Nyata / Bebas yang mencipta semula permainan Westwood awal seperti Command & Conquer klasik: Makluman Mera...
Pasang Dolphin Emulator terkini untuk Gamecube & Wii di Linux
Dolphin Emulator membolehkan anda memainkan permainan Gamecube & Wii pilihan anda di Komputer Peribadi Linux (PC). Menjadi emulator permainan sumber ...