Material on function pointers and member function pointers is available in a variety of books and online sources. We’re doing a review here because it makes understanding boost::function and boost::bind much easier.
Function Pointers
Given:
|
1 2 3 |
double sin(double theta);
double cos(double theta);
double tan(double theta); |
We wish to declare a function pointer that can refer to any of those functions. As a practical matter, function pointer declarations include typedef. The code below creates a function pointer that takes a double as an argument and returns a double.
- First, we declare a function pointer using a
typedef. - Second, we assign a variable of type
TrigFuncto the address ofsin(). - Create an angle,
in radians.
- Use the function pointer to calculate
- Create an array of function pointers to each of
,
,
.
- Invoke each of the trigonometric functions by dereferencing elements of the
TrigFuncarray.
|
1 2 3 4 5 6 7 8 9 10 11 12 |
#includevoid functionPointerExample() {
typedef double (*TrigFunc)(double);
TrigFunc pS = &sin; // notice that there is no * on pS
double theta = 3.1415/4;
double h = (*pS)(theta); // we have to dereference pS with *
static const int N=3;
TrigFunc func[N] = { &sin, &cos, &tan };
double result[N];
for (int i=0; i<N; i++) {
result[i] = (*func[i])(theta);
} // end for |
Admittedly, the syntax is not, ahhh, intuitive. Don’t shoot the messenger.
Member Function Pointers
What is a class? A class is data coupled with the functions that operate on that data. With this in mind, consider that C++ requires an instance pointer to use (non-static) pointers to non-static member functions. Because of the possibility of virtual member functions and the vtable (or its moral equivalent), there is no guarantee on the size of member function pointers. I’ve seen them range from 8bit to 128bit on different platforms. Do not assume that a member function pointer fits in an int.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
void memberFunctionPointerExample() {
using namespace std;
// member function pointer not only has a signature but
// also a class. An instance of the class is required to
// call a non-static member function pointer.
typedef const char* (string::*MemberFunc)() const ;
// Address is of the function const char* std::string::c_str() const;
MemberFunc pMF = &string::c_str;
// Make a class instance
string helloStr("hello");
// Using the string instance to provide context,
// invoke the member function pointer.
const char* pChar = (helloStr.*pMF)();
} // end memberFunctionPointerExample() |
Tutorial Videos
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
#include <iostream>
int add(int x,int y) {
return x+y;
} // end add()
typedef int (*TwoArgFn)(int,int);
class Offset {
int m_offset;
public:
Offset(int offset) : m_offset(offset) {}
int translate(int x) const { return m_offset + x; }
int getOffset() const { return m_offset; }
static int magicNumber() { return 7; }
}; // end class Offset
typedef int (Offset::*MemFn)(int) const;
typedef int (*ZeroArgFn)();
int main(int argc,char* argv[]) {
using namespace std;
TwoArgFn pFn = &add;
int a=7;
int b=9;
int sum = (*pFn)(a,b);
cout << "a=" << a << ", b=" << b << " a+b=" << sum << "\n";
MemFn pMemFn = &Offset::translate;
Offset offset(42);
int nextA = (offset.*pMemFn)(a); // member function pointers must be called in the context of an instance variable
cout << "Before translation a=" << a << ", will translate by " << offset.getOffset()
<< " result of translation nextA=" << nextA << "\n";
ZeroArgFn pZeroArg = &Offset::magicNumber; // static member functions are just like file scope functions
cout << "Result of calling pZeroArg=" << (*pZeroArg)() << "\n";
return 0;
} // end main() |
Related posts:
Related posts brought to you by Yet Another Related Posts Plugin.
Tags: c++, function pointer, member function pointer
Pingback: Start using boost::thread in C++ in 5 minutes | Advanced C++