1 Define a Function Pointer
Regarding their syntax, there are two different types of function pointers:On the one hand there are pointers to ordinary C functions or to static C++ member functions. On the other hand there are pointers to non-static C++ member functions. The basic difference is that all pointers to non-static member functions need a hidden argument: The this-pointer to an instance of the class.
Always keep in mind: These two types of function pointers are incompatible with each other.
Since a function pointer is nothing else than a variable, it must be defined as usual. In the following example we define three function pointers named pt2Function, pt2Member and pt2ConstMember. They point to functions, which take one float and two char and return an int. In the C++ example it is assumed, that the functions, our pointers point to, are (non-static) member functions of TMyClass.
// 2.1 define a function pointer and initialize to NULL
int (*pt2Function)(float, char, char) = NULL; // C
int (TMyClass::*pt2Member)(float, char, char) = NULL; // C++
int (TMyClass::*pt2ConstMember)(float, char, char) const = NULL; // C++
// 2.2 define the calling convention
void __cdecl DoIt(float a, char b, char c); // Borland and Microsoft
void DoIt(float a, char b, char c) __attribute__((cdecl)); // GNU GCC
// 2.3 assign an address to the function pointer
// Note: Although you may ommit the address operator on most compilers
// you should always use the correct way in order to write portable code.
// C
int DoIt (float a, char b, char c){ printf("DoIt\n"); return a+b+c; }
int DoMore(float a, char b, char c)const{ printf("DoMore\n"); return a-b+c; }
pt2Function = DoIt; // short form
pt2Function = &DoMore; // correct assignment using address operator
// C++
class TMyClass
{
public:
int DoIt(float a, char b, char c){ cout << "TMyClass::DoIt"<< endl; return a+b+c;};
int DoMore(float a, char b, char c) const
{ cout << "TMyClass::DoMore" << endl; return a-b+c; };
/* more of TMyClass */
};
pt2ConstMember = &TMyClass::DoMore; // correct assignment using address operator
pt2Member = &TMyClass::DoIt; // note: may also legally point to &DoMore
// 2.4 comparing function pointers
// C
if(pt2Function >0){ // check if initialized
if(pt2Function == &DoIt)
printf("Pointer points to DoIt\n"); }
else
printf("Pointer not initialized!!\n");
// C++
if(pt2ConstMember == &TMyClass::DoMore)
cout << "Pointer points to TMyClass::DoMore" << endl;
// 2.5 calling a function using a function pointer
int result1 = pt2Function (12, 'a', 'b'); // C short way
int result2 = (*pt2Function) (12, 'a', 'b'); // C
TMyClass instance1;
int result3 = (instance1.*pt2Member)(12, 'a', 'b'); // C++
int result4 = (*this.*pt2Member)(12, 'a', 'b'); // C++ if this-pointer can be used
TMyClass* instance2 = new TMyClass;
int result4 = (instance2->*pt2Member)(12, 'a', 'b'); // C++, instance2 is a pointer
delete instance2;
//------------------------------------------------------------------------------------
// 2.6 How to Pass a Function Pointer
// is a pointer to a function which returns an int and takes a float and two char
void PassPtr(int (*pt2Func)(float, char, char))
{
int result = (*pt2Func)(12, 'a', 'b'); // call using function pointer
cout << result << endl;
}
// execute example code - 'DoIt' is a suitable function like defined above in 2.1-4
void Pass_A_Function_Pointer()
{
cout << endl << "Executing 'Pass_A_Function_Pointer'" << endl;
PassPtr(&DoIt);
}
//------------------------------------------------------------------------------------
// 2.7 How to Return a Function Pointer
// 'Plus' and 'Minus' are defined above. They return a float and take two float
// Direct solution: Function takes a char and returns a pointer to a
// function which is taking two floats and returns a float.
// specifies which function to return
float (*GetPtr1(const char opCode))(float, float)
{
if(opCode == '+')
return &Plus;
else
return &Minus; // default if invalid operator was passed
}
// Solution using a typedef: Define a pointer to a function which is taking
// two floats and returns a float
typedef float(*pt2Func)(float, float);
// Function takes a char and returns a function pointer which is defined
// with the typedef above. specifies which function to return
pt2Func GetPtr2(const char opCode)
{
if(opCode == '+')
return &Plus;
else
return &Minus; // default if invalid operator was passed
}
// Execute example code
void Return_A_Function_Pointer()
{
cout << endl << "Executing 'Return_A_Function_Pointer'" << endl;
// define a function pointer and initialize it to NULL
float (*pt2Function)(float, float) = NULL;
pt2Function=GetPtr1('+'); // get function pointer from function 'GetPtr1'
cout << (*pt2Function)(2, 4) << endl; // call function using the pointer
pt2Function=GetPtr2('-'); // get function pointer from function 'GetPtr2'
cout << (*pt2Function)(2, 4) << endl; // call function using the pointer
}
//------------------------------------------------------------------------------------
// 2.8 How to Use Arrays of Function Pointers
// C ---------------------------------------------------------------------------------
// type-definition: 'pt2Function' now can be used as type
typedef int (*pt2Function)(float, char, char);
// illustrate how to work with an array of function pointers
void Array_Of_Function_Pointers()
{
printf("\nExecuting 'Array_Of_Function_Pointers'\n");
// define arrays and ini each element to NULL,and are arrays
// with 10 pointers to functions which return an int and take a float and two char
// first way using the typedef
pt2Function funcArr1[10] = {NULL};
// 2nd way directly defining the array
int (*funcArr2[10])(float, char, char) = {NULL};
// assign the function's address - 'DoIt' and 'DoMore' are suitable functions
// like defined above in 2.1-4
funcArr1[0] = funcArr2[1] = &DoIt;
funcArr1[1] = funcArr2[0] = &DoMore;
/* more assignments */
// calling a function using an index to address the function pointer
printf("%d\n", funcArr1[1](12, 'a', 'b')); // short form
printf("%d\n", (*funcArr1[0])(12, 'a', 'b')); // "correct" way of calling
printf("%d\n", (*funcArr2[1])(56, 'a', 'b'));
printf("%d\n", (*funcArr2[0])(34, 'a', 'b'));
}
// C++ -------------------------------------------------------------------------------
// type-definition: 'pt2Member' now can be used as type
typedef int (TMyClass::*pt2Member)(float, char, char);
// illustrate how to work with an array of member function pointers
void Array_Of_Member_Function_Pointers()
{
cout << endl << "Executing 'Array_Of_Member_Function_Pointers'" << endl;
// define arrays and ini each element to NULL,and are
// arrays with 10 pointers to member functions which return an int and take
// a float and two char
// first way using the typedef
pt2Member funcArr1[10] = {NULL};
// 2nd way of directly defining the array
int (TMyClass::*funcArr2[10])(float, char, char) = {NULL};
// assign the function's address - 'DoIt' and 'DoMore' are suitable member
// functions of class TMyClass like defined above in 2.1-4
funcArr1[0] = funcArr2nd use an array of function pointers in C and C++. The first way uses a typedef, the second way directly defines the array. It's up to you which way you prefer.
[1] = &TMyClass::DoIt;
funcArr1[1] = funcArr2[0] = &TMyClass::DoMore;
/* more assignments */
// calling a function using an index to address the member function pointer
// note: an instance of TMyClass is needed to call the member functions
TMyClass instance;
cout << (instance.*funcArr1[1])(12, 'a', 'b') << endl;
cout << (instance.*funcArr1[0])(12, 'a', 'b') << endl;
cout << (instance.*funcArr2[1])(34, 'a', 'b') << endl;
cout << (instance.*funcArr2[0])(89, 'a', 'b') << endl;
}
No comments:
Post a Comment