Function Pointer Basic
From GameDevID
Author: uray
Kegunaan pointer yang utama adalah untuk menyimpan alamat memori dari sebuah variabel (data type atau object dari class). Selain menyimpan alamat dari variabel, pointer juga dapat digunakan untuk menyimpan alamat dari sebuah fungsi (function pointer).
Function pointer telah digunakan sejak dikenalkannya bahasa C,dan banyak digunakan untuk sebuah fungsi callback atau untuk meningkatkan readability dari sebuah code
Anda dapat memperlakukan function pointer seperti pointer biasa (pointer ke datatype/object), anda dapat menyimpan,mengirimkan, merubah address, atau meng-evaluasi address dari pointer ke fungsi ini dengan sifat tambahan anda dapat memanggil fungsi yang ditunjuk oleh function pointer.
Contents |
Deklarasi
<type> (*<func.Name>)(<argument,..,..>);
Contoh Source Code
1 int tambah(int op1,int op2){ return op1+op2; }
2 int kurang(int op1,int op2){ return op1-op2; }
3
4 int main(void)
5 {
6 int (*fpOperasi)(int op1,int op2);
7 fpOperasi = tambah;
8 printf("hasil panggil langsung : %d\n",tambah(10,5));
9 printf("hasil operasi func.pointer : %d\m",fpOperasi(10,5);
10
11 fpOperasi = kurang;
12
13 printf("hasil operasi func.pointer : %d\m",fpOperasi(10,5);
14 }
Penjelasan
baris ke-6 adalah deklarasi function pointer, yaitu pointer dengan nama fpOperasi yang menunjuk kesuatu fungsi dengan return type int dan memiliki 2 argument integer.
Baris ke-7 inisialisasi fpOperasi agar menunjuk ke fungsi tambah Baris ke-8 pemanggilan fungsi tambah secara langsung Baris ke-9 Pemanggilan fungsi tambah melalui function pointer Baris ke-11 merubah isi fpOperasi agar menunjuk ke fungsi kurang Baris ke-13 Panggil fungsi yang ditunjuk function pointer
contoh 2 (callback/error handling)
Penggunaan Function Pointer
pada contoh ini akan diperlihatkan contoh penggunakan function pointer untuk membuat sebuah mekanisme callback, pada contoh ini kita membuat sebuah fungsi pembagi dengan op1/op2, dimana kita harus mencegah op2=0
int bagi(int op1,int op2,bool (*fpTest)(int op1,int op2))
{
if(fpTest != NULL)
{
if(fpTest(op1,op2) == false)return -1;
}
return op1/op2;
}
bool Verifier(int op1,int op2)
{
if(op2==0)
{
printf("\nerror:Operand2 berisi 0 mengakibatkan division by zero");
return false;
}
if(op1 < op2)
{
printf("\nwarning:Operand1 < Operand2");
return true;
}
else return true;
}
int main(void)
{
printf("a) hasil 4/2 = %d",bagi(4,2,Verifier));
printf("b) hasil 4/0 = %d",bagi(4,0,Verifier));
printf("c) hasil 2/4 = %d",bagi(2,4,Verifier));
printf("d) hasil 2/4 = %d",bagi(2,4,NULL));
}
pada contoh diatas fungsi Verifier dikirimkan melalui argument dari fungsi bagi untuk digunakan sebagai verifier operand sebelum dilakukan operasi pembagian.
Bila operand dari operasi pembagian tidak valid maka fungsi verifier memberikan pesan dan me-return false agar fungsi bagi tidak melanjutkan operasi pembagian
Array pada Function Pointer
int tambah(int op1,int op2){ return op1+op2; }
int kurang(int op1,int op2){ return op1-op2; }
int kali(int op1,int op2){ return op1*op2; }
int bagi(int op1,int op2){ return op1/op2; }
int main(void)
{
int (*fpOperasi[4])(int op1,int op2);
fpOperasi[0] = tambah;
fpOperasi[1] = kurang;
fpOperasi[2] = kali;
fpOperasi[3] = bagi;
int op1,op2,operasi;
printf("op1:"); scanf("%d",&op1);
printf("op2:"); scanf("%d",&op2);
printf("operasi:\n1.Tambah\n2.Kurang\n3.Kali\n4.Bagi\n");
scanf("%d",&operasi);
int hasil = fpOperasi[operasi-1](op1,op2);
printf("operasi %d dengan op1=%d , op2=%d = %d",operasi,op1,op2,hasil);
}
Function Pointer ke Static Class Member Function
penggunaan function pointer pada C++ dibatasi, yaitu function pointer tidak boleh menunjuk pada function yang berada dalam sebuah class (class member function) kecuali function tersebut berjenis static.
class A
{
private :
public : static void WriteString(char* String);
};
void A::WriteString(char* String)
{
printf("A::WriteString() : %s",String);
}
class B
{
private :
public : void Func(void (*Writer)(char* str));
};
void B::Func(void (*Writer)(char* str))
{
Writer("class B writing \"hello...!\"");
}
int main(void)
{
A* a = new A;
B* b = new B;
b->Func(a->WriteString);
delete a;
delete b;
}
Namun terkadang yang menjadi masalah adalah, sebuah member function yang berjenis static, tidak memiliki akses ke member dari class, sebagai contoh bila kita rubah class A menjadi :
class A
{
private : int privatenumber;
public : static void WriteString(char* String);
};
void A::WriteString(char* String)
{
printf("A::privatenumber = %d",privatenumber);
printf("A::WriteString() : %s",String);
}
.
.
maka compiler menyatakan error, bahwa fungsi static tidak dapat mengakses member dari class A. Namun bila kita rubah fungsi WriteString menjadi non-static (dengan menghapus keyword "static") maka fungsi WriteString tidak dapat di pass melalui argument ke B::func (karena function pointer tidak boleh menunjuk fungsi yang merupakan member class)
Function Pointer to Non-static Class Member Function
Salah satu cara agar kita dapat membuat function pointer yang menunjuk ke non-static class member function bekerja adalah dengan cara memberikan object dari class yang membernya ingin diakses
Pada masalah sebelumnya A::WriteString memerlukan akses ke private member dari A yaitu mengakses int A:rivatenumber, maka solusinya kita pass object dari class A ke argumen dari A::WriteString
kode yang sebelumnya dirubah menjadi :.
class A
{
private : int privatenumber;
public : static void WriteString(char* String,A* Self);
};
void A::WriteString(char* String,A* Self)
{
printf("A::privatenumber = %d\n",Self->privatenumber);
printf("A::WriteString() : %s",String);
}
class B
{
private :
public : void Func(void (*Writer)(char* str,A* Self),A* NeedToPass);
};
void B::Func(void (*Writer)(char* str,A* Self),A* NeedToPass)
{
Writer("class B writing \"hello...!\"",NeedToPass);
}
int main(void)
{
A* a = new A;
B* b = new B;
b->Func(a->WriteString,a);
delete a;
delete b;
}
Terdapat cara lain menggunakan member function pointer selain dengan cara di atas. Beberapa hal yang harus diperhatikan adalah:
1. Deklarasi Member function harus dengan menggunakan operator ::*
2. Member function pointer memerlukan objek atau pointer ke objek supaya dapat digunakan.
3. Memanggil member function pointer menggunakan operator .* atau ->* , tergantung apakah digunakan dengan objek (atau reference) atau dengan pointer. Yang menjadi masalah di sini adalah kedua operator tersebut memiliki prioritas yang lebih rendah daripada operator aplikasi fungsi, sehingga anda akan selalu memerlukan tanda kurung untuk menggunakan member function pointer.
4. Assignment ke member function pointer harus selalu menggunakan operator &. Hal ini berbeda dengan function pinter biasa dimana operator & adalah optional. Beberapa kompiler akan menerima konstruk assignment tanpa operator &, tapi itu tidak standard. Kompiler yang sesuai dengan standard C++98 akan mereject assignment member function pointer tanpa operator &.
untuk lebih jelasnya anda dapat melihat contoh program di bawah:
#include <iostream>
using std::cout;
using std::endl;
class SomeMumboJumboClass{
int i;
public:
void a_method();
SomeMumboJumboClass(int p):i(p){}
};
void SomeMumboJumboClass::a_method(){
cout << "the mumbo jumbo class has a member variable with value = "<< i<< endl;
}
typedef void (SomeMumboJumboClass::* MemberFunctionptr)() ; // ini cara mendekrarasikan typedef dari non-static member function
// this is the usual way to use member function pointer
int main(){
SomeMumboJumboClass c(2); // deklarasikan sebuah objek
void (SomeMumboJumboClass::* the_mem_fun_ptr)(); // deklarasikan member function variabel bernama the_mem_fun_ptr
the_mem_fun_ptr = &SomeMumboJumboClass::a_method; // the_mem_fun_ptr sekarang menunjuk pada SomeMumboJumboClass::a_method
// perhatikan operator & didepan nama function member
c.a_method(); // pemanggilan tanpa function pointer
(c.*the_mem_fun_ptr)(); // pemanggilan dengan function pointer
SomeMumboJumboClass* d = new SomeMumboJumboClass(3); // ini adalah pointer ke objek
d->a_method(); // pemanggilan normal
(d->* the_mem_fun_ptr)(); // pemanggilan dengan pointer fungsi
MemberFunctionptr the_mem_fun_ptr2 = &SomeMumboJumboClass::a_method; // deklarasi dan definisi member function pointer
// menggunakan typedef di atas. this is my preferred style.
(c.* the_mem_fun_ptr2)(); // bisa digunakan seperti ini
(d->* the_mem_fun_ptr2) (); // atau seperti ini
delete d;
}
yah begitulah kira-kira... article ini hanya sebagai langkah awal saja bagi yang belum mengetahui function pointer, asalnya artikelnya mau sampai pembuatan functor, callback implementation, virtual function problem dan lain-lain..
