Chapter 38. Pointers to Member Functions

FAQ 38.01 What is the type of a pointer to a nonstatic member function?

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.

image

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.

image

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.

FAQ 38.02 Can pointers to nonstatic member functions be passed to signal handlers, X event call-back handlers, and so on, that expect C-like function pointers?

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).

image

FAQ 38.03 What is one of the most common errors when using pointers to member functions?

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.

FAQ 38.04 How is an array of pointers to nonstatic member functions declared?

Use a typedef.

Consider the following class example.

image

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.

image

The output of this program is as follows.

image

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset