Function pointer (con trỏ hàm) và Callback function trong C++

Chúng ta có thể xem Function pointer như là một biến đặc biệt có thể chứa địa chỉ của một function.

void (*fp)(int)               // con trỏ fp trỏ đến một func có input là int, không trả về giá trị
int (*fp)(double, double)     // con trỏ fp trỏ đến một func có 2 input là double và trả về int 

Dùng Function pointer khi cần pass một function (như data), hoặc khi cần gọi function đó một cách gián tiếp

#include <iostream>
void hello(int x) {
    std::cout << "Hello, number " << x << "\n";
}
void goodbye(int x) {
    std::cout << "Goodbye, number " << x << "\n";
}
int main() {
    // Declare a function pointer type: takes int, returns void
    void (*funcptr)(int);

    // Point it to hello
    funcptr = &hello;
    funcptr(42);  // calls hello(42)

    // Point it to goodbye
    funcptr = &goodbye;
    funcptr(99);  // calls goodbye(99)

    return 0;
}

Hoặc dùng làm callback

Ưu điểm

  • Linh hoạt: Người dùng có thể truyền bất kỳ hàm nào (sendMail, sendSMS,…) mà không cần sửa doTask.
  • Tách biệt logic: doTask chỉ lo xử lý tác vụ, còn hậu xử lý do callback quyết định.
  • Tái sử dụng: Một hàm doTask có thể dùng cho nhiều tình huống khác nhau.
#include <iostream>
void sendMail(const string& msg) {
    cout << "[MAIL] Gửi email: " << msg << endl;
}
void sendSMS(const string& msg) {
    cout << "[SMS] Gửi tin nhắn: " << msg << endl;
}
void doTask() {
  // do something
  sendMail("task done");  // phải sửa hàm doTask() mỗi lần muốn sửa hậu xử lý thành sendSMS() or ...
}
int main() {
    doTask();
    return 0;
}
#include <iostream>
void sendMail(const string& msg) {
    cout << "[MAIL] Gửi email: " << msg << endl;
void sendSMS(const string& msg) {
    cout << "[SMS] Gửi tin nhắn: " << msg << endl;
}
void doTask(void (*callback)(const string&)) {
    // do something
    callback("task done");  // linh hoạt hơn, caller sẽ truyền callback
}
int main() {
    doTask(sendMail);  // truyền callback gửi mail
    doTask(sendSMS);   // truyền callback gửi SMS
    return 0;
}

Leave a Comment