Function Pointers, part 2 - Defining and Using C Member Function Pointers
(Page 2 of 4 )
Though a function pointer to a member function looks a bit more complex, it shouldn’t be too difficult to understand how they work now. Here is the function pointed at by the example:
bool ProtocolImpl::login(string const &msg, RQRSTable const *rt);
And this is the typedef I used to define the function pointer as used in the example struct:
typedef bool (ProtocolImpl::*HandleFunc)
(string const&, struct RQRSTable*);
It all doesn’t look that different from the regular function pointer syntax when you take a closer look at it. The main difference lies in the fact that you have to specify the class scope of the function pointer, so that the compiler understands that the function pointer is aimed at the member of a class.
Of course there are more ways to declare a member function in a class, so let’s use this simple class definition to try them out:
class MyClass {
public:
MyClass() : m_value(0) {}
void SetValue(int value) { m_value=value; }
int GetValue() const { return m_value; }
inline void InlineFoo() { (void)printf(“inlined\n”); }
static void foo(char const *msg, int value)
{ (void)printf(“%s %d\n”, msg, value); }
private:
int m_value;
};
The function pointer comparable to the one used in the example struct is one that points to void MyClass::SetValue(int):
// raw declaration and assignment
void (MyClass::*svalue)(int) = &MyClass::SetValue;
// utilizing a typedef
typedef void (MyClass:*SValue)(int);
SValue svalue = &MyClass::SetValue;
So you see that the function pointer to a member function only needs ‘MyClass::’ in front of the variable name to declare it (which is probably the reason why it instinctively looks a bit weird). Member functions can have more identities than this one so let’s see how we define pointers to the other functions.
// raw declaration and assignment
int (MyClass::*gvalue)() const = &MyClass::GetValue;
// utilizing a typedef
typedef void (MyClass::GValue)() const;
GValue gvalue = &MyClass::GetValue;
A const member function pointer is defined the same way we have been declaring function pointers up to now: just add const.
// raw declaration and assignment
void (MyClass::*inlfoo)() = &MyClass::InlineFoo;
// utilizing a typedef
typedef void (MyClass::*InlFoo)();
InlFoo infloo = &MyClass::InlineFoo;
The function pointer above may come as a small surprise, because you would expect the code of an inlined member function to be pasted into where we normally would find the function call. However when you declare a member function pointer to an inlined function, the compiler creates a body for that function so that it can be executed when you call that member function pointer.
// raw declaration and assignment
void (*foo)(char const*, int) = &MyClass::foo;
// utilizing a typedef
typedef void (*FooPtr)(char const*, int);
FooPtr foo = &MyClass::foo;
Can you guess which member function is being pointed at by FooPtr without having to go back to the declaration of MyClass?
It is pointing at: ‘static void foo (char const * msg, int val );’ Again this may come a bit unexpected, but pointers to static member functions are declared just like the regular function pointers. And when you think about it… static member functions can be used just like regular functions, with them main difference being the fact that you have to provide the class scope (‘MyClass::’) when calling them.
Defining member function pointers is one thing; now let’s see how we use them. There are some specifics you have to be aware of when calling member functions in objects. Let’s write some code that tests the above defined member function pointers.
int main (int argc, char *argv[]) { =
MyClass myclass;
SValue svalue = &MyClass::SetValue;
(myclass.*svalue)(0x1234);
GValue gvalue = &MyClass::GetValue;
int res = (myclass.*gvalue)();
(void)printf(“result is 0x%d\n”, res);
InlineFoo inlinefoo = &MyClass::InlineFoo;
(myclass.*inlinefoo)();
FooPtr fooptr = &MyClass::foo;
Fooptr(“result is: “, (myclass.*gvalue)());
}
It will generate the following output:
result is 0x00001234
inlined
result is: 4660
When you plan to use a member function pointer you will need an object of the class you are going to use it on. The syntax boils down to (myobject.*fncptr)(), where <MYOBJECT.> is the name of the instantiated class and <*FNCPTR> is the name of the used member function pointer.
Next: C Member Function Pointers and Polymorphism >>
More C++ Articles
More By J. Nakamura