The most important thing to understand is that the type is different from that of a pointer to a C-style (non-member) function. Simply understanding that they are completely different and have incompatible types will prevent the most common and dangerous errors with pointers to member functions.
A pointer to the nonstatic member function with signature void Fred::f(int)
has type void(Fred::*)(int)
. In particular, the type of the pointer to a nonstatic member function includes the class of the member function because nonstatic member functions have an implicit parameter that points to the object (the this
pointer).
Here's an example.
Note the use of the typedef
. Because of the rather obscure syntax of pointers to nonstatic member functions, it is highly recommended that a typedef
be used to represent the pointer type.
In the following example, a pointer p
is created to point to Fred::g
. This pointer is then used to call the member function.
The output of this program is as follows.
Fred::g(int); i=42
A pointer to a nonstatic member function of class Fred
has a totally different type from a pointer to a function. For example, the pointer type void(Fred::*)(int)
is totally different from the pointer type void(*)(int)
. Do not use a cast to try to convert between the two types. You have been warned.
A pointer to a static member function of class Fred
has the same type as a pointer to a C-like function. In other words, a C-like function or static member function can be converted to the same pointer to function type, such as void(*)(int)
. But a pointer to a nonstatic member function cannot be converted to a normal pointer to a function type.
A pointer to a nonstatic member function cannot be passed into a routine that is expecting a pointer to a C-like function, since a nonstatic member function is meaningless without there being an object to which the nonstatic member function can be applied.
To simulate this behavior, pass a pointer to a C-like function, and have that function obtain the object pointer through some other technique (such as storing it in a global). The C-like function would then call the desired nonstatic member function. For example, suppose x.f(int)
were to be called on interrupt, where f(int)
is a nonstatic member function of the class of object x
. The following would accomplish the call (note that a static member function has the same type as a C-like function).
Trying to pass the address of a nonstatic member function into a function that is expecting a pointer to function, and sometimes the inverse of this scenario.
Nonstatic member functions have an implicit parameter that points to the object—the pointer called this
inside the member function. Nonstatic member functions can be thought of as having a different calling convention from that of normal C functions, so the types of their pointers are different and incompatible—pointer to nonstatic member function versus pointer to function.
C++ introduces a new type of pointer, called a pointer to nonstatic member, which can be invoked only by providing an object. Do not attempt to cast a pointer that points to a nonstatic member function into a pointer to function or vice versa; the result is undefined and probably disastrous. For example, a pointer to nonstatic member function probably doesn't contain the machine address of the appropriate function. As noted in the last example, if a regular C function pointer is needed, use either a static member function or a nonmember function.
Use a typedef
.
Consider the following class example.
Since FredMemberPtr
is a typedef
, it can be used like most other data types. In particular, an array of FredMemberPtr
can be created using the following syntax.
FredMemberPtr array[3] = { &Fred::f, &Fred::g, &Fred::h };
To call one of the nonstatic member functions, supply a Fred
object, and use the .* operator.
The output of this program is as follows.