Λειτουργία επανάκλησης σε C ++

Callback Function C



Μια συνάρτηση επανάκλησης είναι μια συνάρτηση, η οποία είναι ένα όρισμα, όχι μια παράμετρος, σε μια άλλη συνάρτηση. Η άλλη συνάρτηση μπορεί να ονομαστεί κύρια συνάρτηση. Επομένως, εμπλέκονται δύο συναρτήσεις: η κύρια λειτουργία και η ίδια η λειτουργία επανάκλησης. Στη λίστα παραμέτρων της κύριας συνάρτησης, υπάρχει η δήλωση της συνάρτησης κλήσης χωρίς τον ορισμό της, όπως και οι δηλώσεις αντικειμένων χωρίς εκχώρηση. Η κύρια συνάρτηση καλείται με ορίσματα (στο κύριο ()). Ένα από τα επιχειρήματα στην κλήση κύριας συνάρτησης είναι ο αποτελεσματικός ορισμός της συνάρτησης επανάκλησης. Στο C ++, αυτό το όρισμα είναι μια αναφορά στον ορισμό της συνάρτησης επανάκλησης. δεν είναι ο πραγματικός ορισμός. Η ίδια η λειτουργία επανάκλησης καλείται στην πραγματικότητα μέσα στον ορισμό της κύριας συνάρτησης.

Η βασική λειτουργία επανάκλησης στο C ++ δεν εγγυάται ασύγχρονη συμπεριφορά σε ένα πρόγραμμα. Η ασύγχρονη συμπεριφορά είναι το πραγματικό όφελος του σχήματος συνάρτησης επανάκλησης. Στο σχήμα ασύγχρονης συνάρτησης κλήσης, το αποτέλεσμα της κύριας συνάρτησης θα πρέπει να ληφθεί για το πρόγραμμα προτού επιτευχθεί το αποτέλεσμα της συνάρτησης επανάκλησης. Είναι δυνατόν να γίνει αυτό σε C ++. Ωστόσο, το C ++ έχει μια βιβλιοθήκη που ονομάζεται μέλλον για να εγγυηθεί τη συμπεριφορά του σχήματος ασύγχρονης λειτουργίας επανάκλησης.







Αυτό το άρθρο εξηγεί το βασικό σχήμα συνάρτησης επανάκλησης. Πολλά είναι με καθαρό C ++. Όσον αφορά την επανάκληση, εξηγείται επίσης η βασική συμπεριφορά της μελλοντικής βιβλιοθήκης. Βασικές γνώσεις για το C ++ και τους δείκτες του είναι απαραίτητες για την κατανόηση αυτού του άρθρου.



Περιεχόμενο άρθρου

Βασικό σχήμα λειτουργίας επανάκλησης

Ένα σχήμα συνάρτησης επανάκλησης χρειάζεται μια κύρια συνάρτηση και την ίδια τη λειτουργία επανάκλησης. Η δήλωση της συνάρτησης επανάκλησης είναι μέρος της λίστας παραμέτρων της κύριας συνάρτησης. Ο ορισμός της συνάρτησης επανάκλησης υποδεικνύεται στην κλήση συνάρτησης της κύριας συνάρτησης. Η συνάρτηση επανάκλησης καλείται στην πραγματικότητα μέσα στον ορισμό της κύριας συνάρτησης. Το παρακάτω πρόγραμμα το δείχνει:



#περιλαμβάνω

χρησιμοποιώντας ονομαστικου χωρουώρες?



intmainFn(απανθρακώνωκεφ[],int (*ptr)(int))

{

intid1= 1?

intid2= 2?

intσυνήθως= (*ptr)(id2)?

κόστος<<'κύρια λειτουργία:'<<id1<<''<<κεφ<<''<<συνήθως<<' n'?

ΕΠΙΣΤΡΟΦΗid1?

}


intγβ(intταυτότητα)

{

κόστος<<'λειτουργία επανάκλησης'<<' n'?

ΕΠΙΣΤΡΟΦΗταυτότητα?

}


intκύριος()

{

int (*ptr)(int) = &γβ?

απανθρακώνωόχι[] = 'και'?

mainFn(πατέρας, cb)?



ΕΠΙΣΤΡΟΦΗ 0?

}

Η έξοδος είναι:





λειτουργία επανάκλησης

κύρια λειτουργία: 1 και 2

Η κύρια λειτουργία προσδιορίζεται από το principalFn (). Η συνάρτηση επανάκλησης αναγνωρίζεται από το cb (). Η συνάρτηση επανάκλησης ορίζεται εκτός της κύριας συνάρτησης αλλά στην πραγματικότητα καλείται εντός της κύριας συνάρτησης.

Σημειώστε τη δήλωση της συνάρτησης επανάκλησης ως παράμετρο στη λίστα παραμέτρων της δήλωσης κύριας λειτουργίας. Η δήλωση της συνάρτησης επανάκλησης είναι int (*ptr) (int). Σημειώστε την έκφραση συνάρτησης επανάκλησης, όπως μια κλήση συνάρτησης, στον ορισμό της κύριας συνάρτησης. οποιοδήποτε όρισμα για την κλήση συνάρτησης επανάκλησης περνά εκεί. Η δήλωση για αυτήν την κλήση συνάρτησης είναι:



intσυνήθως= (*ptr)(id2)?

Όπου το id2 είναι επιχείρημα. Το ptr είναι μέρος της παραμέτρου, ενός δείκτη, που θα συνδεθεί με την αναφορά της συνάρτησης επανάκλησης στην κύρια () συνάρτηση.

Σημειώστε την έκφραση:

int (*ptr)(int) = &γβ?

Στην κύρια συνάρτηση (), η οποία συνδέει τη δήλωση (χωρίς ορισμό) της συνάρτησης επανάκλησης με το όνομα του ορισμού της ίδιας συνάρτησης επανάκλησης.

Η κύρια συνάρτηση καλείται, στη συνάρτηση main (), ως:

mainFn(πατέρας, cb)?

Όπου το cha είναι μια συμβολοσειρά και το cb είναι το όνομα της συνάρτησης επανάκλησης χωρίς κανένα όρισμα της.

Σύγχρονη συμπεριφορά της λειτουργίας επανάκλησης

Εξετάστε το ακόλουθο πρόγραμμα:

#περιλαμβάνω

χρησιμοποιώντας ονομαστικου χωρουώρες?



κενόςmainFn(κενός (*ptr)())

{

κόστος<<«κύρια λειτουργία»<<' n'?

(*ptr)()?

}


κενόςγβ()

{

κόστος<<'λειτουργία επανάκλησης'<<' n'?

}


κενόςfn()

{

κόστος<<'δει'<<' n'?

}


intκύριος()

{

κενός (*ptr)() = &γβ?

mainFn(γβ)?

fn()?



ΕΠΙΣΤΡΟΦΗ 0?

}

Η έξοδος είναι:

κύρια λειτουργία

λειτουργία επανάκλησης

δει

Υπάρχει μια νέα λειτουργία εδώ. Το μόνο που κάνει η νέα λειτουργία είναι να εμφανίζει την έξοδο, εμφανίζεται. Στην κύρια συνάρτηση (), καλείται η κύρια συνάρτηση, κατόπιν η νέα συνάρτηση, fn (). Η έξοδος δείχνει ότι ο κώδικας για την κύρια συνάρτηση εκτελέστηκε, στη συνέχεια ότι για τη συνάρτηση κλήσης εκτελέστηκε και τέλος ότι για τη συνάρτηση fn (). Αυτή είναι η σύγχρονη (μονόκλωνη) συμπεριφορά.

Αν ήταν ασύγχρονη συμπεριφορά, όταν κλήθηκαν τρία τμήματα κώδικα με σειρά, το πρώτο τμήμα κώδικα μπορεί να εκτελεστεί, ακολουθούμενο από την εκτέλεση του τρίτου τμήματος κώδικα, πριν εκτελεστεί το δεύτερο τμήμα κώδικα.

Λοιπόν, η συνάρτηση, fn () μπορεί να κληθεί από τον ορισμό της κύριας συνάρτησης, αντί από τη συνάρτηση main (), ως εξής:

#περιλαμβάνω

χρησιμοποιώντας ονομαστικου χωρουώρες?



κενόςfn()

{

κόστος<<'δει'<<' n'?

}


κενόςmainFn(κενός (*ptr)())

{

κόστος<<«κύρια λειτουργία»<<' n'?

fn()?

(*ptr)()?

}


κενόςγβ()

{

κόστος<<'λειτουργία επανάκλησης'<<' n'?

}


intκύριος()

{

κενός (*ptr)() = &γβ?

mainFn(γβ)?



ΕΠΙΣΤΡΟΦΗ 0?

}

Η έξοδος είναι:

κύρια λειτουργία

δει

λειτουργία επανάκλησης

Αυτή είναι μια μίμηση ασύγχρονης συμπεριφοράς. Δεν είναι ασύγχρονη συμπεριφορά. Εξακολουθεί να είναι σύγχρονη συμπεριφορά.

Επίσης, η σειρά εκτέλεσης του τμήματος κώδικα της κύριας συνάρτησης και του τμήματος κώδικα της συνάρτησης επανάκλησης μπορούν να αντικατασταθούν στον ορισμό της κύριας συνάρτησης. Το παρακάτω πρόγραμμα το δείχνει:

#περιλαμβάνω

χρησιμοποιώντας ονομαστικου χωρουώρες?



κενόςmainFn(κενός (*ptr)())

{

(*ptr)()?

κόστος<<«κύρια λειτουργία»<<' n'?

}


κενόςγβ()

{

κόστος<<'λειτουργία επανάκλησης'<<' n'?

}


κενόςfn()

{

κόστος<<'δει'<<' n'?

}


intκύριος()

{

κενός (*ptr)() = &γβ?

mainFn(γβ)?

fn()?



ΕΠΙΣΤΡΟΦΗ 0?

}

Η έξοδος είναι τώρα,

λειτουργία επανάκλησης

κύρια λειτουργία

δει

Αυτό είναι επίσης μια μίμηση ασύγχρονης συμπεριφοράς. Δεν είναι ασύγχρονη συμπεριφορά. Εξακολουθεί να είναι σύγχρονη συμπεριφορά. Η πραγματική ασύγχρονη συμπεριφορά μπορεί να επιτευχθεί όπως εξηγείται στην επόμενη ενότητα ή με τη βιβλιοθήκη, στο μέλλον.

Ασύγχρονη συμπεριφορά με λειτουργία επανάκλησης

Ο ψευδοκώδικας για το βασικό σχήμα ασύγχρονης λειτουργίας επανάκλησης είναι:

τύπο εξόδου?

πληκτρολογήστε cb(τύπο εξόδου)

{

// δηλώσεις

}


πληκτρολογήστε principalFn(είσοδος τύπου, τύπος cb(τύπο εξόδου))

{

// δηλώσεις

}

Σημειώστε τις θέσεις των δεδομένων εισόδου και εξόδου στα διάφορα σημεία του ψευδοκώδικα. Η είσοδος της συνάρτησης επανάκλησης είναι η έξοδός της. Οι παράμετροι της κύριας συνάρτησης είναι η παράμετρος εισόδου για τον γενικό κώδικα και η παράμετρος για τη συνάρτηση επανάκλησης. Με αυτό το σχήμα, μια τρίτη συνάρτηση μπορεί να εκτελεστεί (ονομάζεται) στην κύρια () συνάρτηση πριν από την ανάγνωση της εξόδου της συνάρτησης επανάκλησης (ακόμα στην κύρια () συνάρτηση). Ο παρακάτω κώδικας το δείχνει αυτό:

#περιλαμβάνω

χρησιμοποιώντας ονομαστικου χωρουώρες?

απανθρακώνω *παραγωγή?


κενόςγβ(απανθρακώνωέξω[])

{

παραγωγή=έξω?

}



κενόςmainFn(απανθρακώνωεισαγωγή[],κενός (*ptr)(απανθρακώνω[πενήντα]))

{

(*ptr)(εισαγωγή)?

κόστος<<«κύρια λειτουργία»<<' n'?

}


κενόςfn()

{

κόστος<<'δει'<<' n'?

}


intκύριος()

{

απανθρακώνωεισαγωγή[] = 'λειτουργία επανάκλησης'?

κενός (*ptr)(απανθρακώνω[]) = &γβ?

mainFn(είσοδος, cb)?

fn()?

κόστος<<παραγωγή<<' n'?



ΕΠΙΣΤΡΟΦΗ 0?

}

Η έξοδος του προγράμματος είναι:

κύρια λειτουργία

δει

λειτουργία επανάκλησης

Σε αυτόν τον συγκεκριμένο κώδικα, το δεδομένο εξόδου και εισόδου τυχαίνει να είναι το ίδιο. Το αποτέλεσμα της τρίτης κλήσης συνάρτησης στην κύρια () λειτουργία εμφανίστηκε πριν από το αποτέλεσμα της συνάρτησης επανάκλησης. Η συνάρτηση επανάκλησης εκτελέστηκε, τελείωσε και εκχώρησε το αποτέλεσμα (τιμή) στη μεταβλητή, έξοδο, επιτρέποντας στο πρόγραμμα να συνεχίσει χωρίς την παρέμβασή του. Στην κύρια συνάρτηση (), η έξοδος της συνάρτησης επανάκλησης χρησιμοποιήθηκε (διαβάστηκε και εμφανίστηκε) όταν ήταν απαραίτητη, οδηγώντας σε ασύγχρονη συμπεριφορά για ολόκληρο το σχήμα.

Αυτός είναι ο τρόπος με ένα σπείρωμα για να αποκτήσετε ασύγχρονη συμπεριφορά συνάρτησης επανάκλησης με καθαρό C ++.

Βασική χρήση της μελλοντικής Βιβλιοθήκης

Η ιδέα του σχεδίου ασύγχρονης συνάρτησης κλήσης είναι ότι η κύρια συνάρτηση επιστρέφει πριν επιστρέψει η συνάρτηση επανάκλησης. Αυτό έγινε έμμεσα, αποτελεσματικά, στον παραπάνω κώδικα.

Σημειώστε από τον παραπάνω κώδικα ότι η λειτουργία επανάκλησης λαμβάνει την κύρια είσοδο για τον κωδικό και παράγει την κύρια έξοδο για τον κώδικα. Η βιβλιοθήκη C ++, μελλοντική, έχει μια λειτουργία που ονομάζεται συγχρονισμός (). Το πρώτο όρισμα σε αυτήν τη συνάρτηση είναι η αναφορά συνάρτησης επανάκλησης. το δεύτερο όρισμα είναι η είσοδος στη συνάρτηση επανάκλησης. Η λειτουργία συγχρονισμού () επιστρέφει χωρίς να περιμένετε να ολοκληρωθεί η εκτέλεση της συνάρτησης κλήσης, αλλά επιτρέπει να ολοκληρωθεί η λειτουργία επανάκλησης. Αυτό παρέχει ασύγχρονη συμπεριφορά. Ενώ η λειτουργία επανάκλησης συνεχίζει να εκτελείται, αφού η λειτουργία συγχρονισμού () έχει ήδη επιστρέψει, οι προτάσεις κάτω από αυτήν συνεχίζουν να εκτελούνται. Αυτό είναι σαν την ιδανική ασύγχρονη συμπεριφορά.

Το παραπάνω πρόγραμμα έχει ξαναγραφεί παρακάτω, λαμβάνοντας υπόψη τη μελλοντική βιβλιοθήκη και τη λειτουργία συγχρονισμού ():

#περιλαμβάνω

#περιλαμβάνω

#περιλαμβάνω

χρησιμοποιώντας ονομαστικου χωρουώρες?

μελλοντικός<σειρά>>παραγωγή?

συμβολοσειρά cb(χορδή stri)

{

ΕΠΙΣΤΡΟΦΗstri?

}



κενόςmainFn(εισαγωγή συμβολοσειράς)

{

παραγωγή=ασύρματη(cb, είσοδος)?

κόστος<<«κύρια λειτουργία»<<' n'?

}


κενόςfn()

{

κόστος<<'δει'<<' n'?

}


intκύριος()

{

εισαγωγή συμβολοσειράς=σειρά('λειτουργία επανάκλησης')?

mainFn(εισαγωγή)?

fn()?

string ret=παραγωγή.παίρνω()? // περιμένει την επιστροφή κλήσης εάν είναι απαραίτητο

κόστος<<σωστά<<' n'?



ΕΠΙΣΤΡΟΦΗ 0?

}

Η λειτουργία συγχρονισμού () αποθηκεύει τελικά την έξοδο της συνάρτησης επανάκλησης στο μελλοντικό αντικείμενο. Η αναμενόμενη έξοδος μπορεί να ληφθεί στη συνάρτηση κύρια (), χρησιμοποιώντας τη συνάρτηση μέλους get () του μελλοντικού αντικειμένου.

συμπέρασμα

Μια συνάρτηση επανάκλησης είναι μια συνάρτηση, η οποία είναι ένα όρισμα, όχι μια παράμετρος, σε μια άλλη συνάρτηση. Ένα σχήμα συνάρτησης επανάκλησης χρειάζεται μια κύρια συνάρτηση και την ίδια τη λειτουργία επανάκλησης. Η δήλωση της συνάρτησης επανάκλησης είναι μέρος της λίστας παραμέτρων της κύριας συνάρτησης. Ο ορισμός της συνάρτησης επανάκλησης υποδεικνύεται στην κλήση συνάρτησης της κύριας συνάρτησης (στην κύρια ()). Η συνάρτηση επανάκλησης καλείται στην πραγματικότητα μέσα στον ορισμό της κύριας συνάρτησης.

Ένα σχήμα συνάρτησης επανάκλησης δεν είναι απαραίτητα ασύγχρονο. Για να βεβαιωθείτε ότι το σχήμα της λειτουργίας επανάκλησης είναι ασύγχρονο, κάντε την κύρια είσοδο στον κώδικα, την είσοδο στη συνάρτηση επανάκλησης. κάντε την κύρια έξοδο του κώδικα, την έξοδο της λειτουργίας επανάκλησης. αποθηκεύστε την έξοδο της συνάρτησης επανάκλησης σε μια μεταβλητή ή δομή δεδομένων. Στην κύρια συνάρτηση (), αφού καλέσετε την κύρια συνάρτηση, εκτελέστε άλλες δηλώσεις της εφαρμογής. Όταν απαιτείται η έξοδος της συνάρτησης επανάκλησης, στην κύρια λειτουργία (), χρησιμοποιήστε την (ανάγνωση και εμφάνιση) εκεί και στη συνέχεια.