Tidak ada yang salah dengan menggunakan pointer fungsi. Namun, pointer ke fungsi anggota non-statis tidak seperti pointer fungsi normal: fungsi anggota perlu dipanggil pada objek yang diteruskan sebagai argumen implisit ke fungsi tersebut. Jadi, tanda tangan dari fungsi anggota Anda di atas adalah
void (aClass::*)(int, int)
daripada tipe yang Anda coba gunakan
void (*)(int, int)
Satu pendekatan dapat terdiri dari membuat fungsi anggota static
dalam hal ini tidak memerlukan objek apa pun untuk dipanggil dan Anda dapat menggunakannya dengan tipe void (*)(int, int)
.
Jika Anda perlu mengakses anggota non-statis kelas Anda dan Anda harus tetap menggunakan pointer fungsi, misalnya, karena fungsinya adalah bagian dari antarmuka C, pilihan terbaik Anda adalah selalu meneruskan a void*
ke fungsi Anda dengan mengambil fungsi pointer dan memanggil anggota Anda melalui fungsi penerusan yang memperoleh objek dari void*
dan kemudian memanggil fungsi anggota.
Dalam antarmuka C ++ yang tepat, Anda mungkin ingin melihat agar fungsi Anda mengambil argumen templated untuk objek fungsi agar menggunakan tipe kelas arbitrer. Jika menggunakan antarmuka templated tidak diinginkan, Anda harus menggunakan sesuatu seperti std::function<void(int, int)>
: Anda dapat membuat objek fungsi yang dapat dipanggil yang sesuai untuk ini, misalnya menggunakan std::bind()
.
Pendekatan tipe-aman menggunakan argumen template untuk tipe kelas atau yang sesuai std::function<...>
lebih disukai daripada menggunakan void*
antarmuka karena mereka menghilangkan potensi kesalahan karena cast ke tipe yang salah.
Untuk memperjelas cara menggunakan penunjuk fungsi untuk memanggil fungsi anggota, berikut ini contohnya:
// the function using the function pointers:
void somefunction(void (*fptr)(void*, int, int), void* context) {
fptr(context, 17, 42);
}
void non_member(void*, int i0, int i1) {
std::cout << "I don't need any context! i0=" << i0 << " i1=" << i1 << "\n";
}
struct foo {
void member(int i0, int i1) {
std::cout << "member function: this=" << this << " i0=" << i0 << " i1=" << i1 << "\n";
}
};
void forwarder(void* context, int i0, int i1) {
static_cast<foo*>(context)->member(i0, i1);
}
int main() {
somefunction(&non_member, 0);
foo object;
somefunction(&forwarder, &object);
}