All About Pointers to Members

A class can have two general categories of members: function members and data members. Likewise, there are two categories of pointers to members: pointers to member functions and pointers to data members. The latter are less common because in general, classes do not have public data members. However, when using legacy C code that contains structs or classes that happen to have public data members, pointers to data members are useful.

Pointers to members are one of the most intricate syntactic constructs in C++, and yet, they are a very powerful feature too. They enable you to invoke a member function of an object without having to know the name of that function. This is very handy implementing callbacks. Similarly, you can use a pointer to data member to examine and alter the value of a data member without knowing its name.

Pointers to Data Members

Although the syntax of pointers to members may seem a bit confusing at first, it's consistent and resembles the form of ordinary pointers, with the addition of the class name followed by the operator :: before the asterisk. For example, if an ordinary pointer to int looks as follows:

int * pi;

You define a pointer to an int member of class A as follows:

int A::*pmi; /* pmi is a pointer to an int member of A*/

You initialize a pointer to member like this:

class A { public: int num; int x; }; int A::*pmi = & A::num; /* 1 */

The statement numbered 1 declares a pointer to an int member of class A and initializes it with the address of the member num. Using pmi and the built-in operator .* you can examine and modify the value of num in any object of class A:

A a1, a2; int n=a1.*pmi; /* copy a1.num to n */ a1.*pmi=5; /* assign the value 5 to a1.num */ a2.*pmi=6; /* assign the value 6 to a2.num */

If you have a pointer to A, you need to use the built-in operator ->* instead:

A * pa=new A; int n=pa->*pmi; pa->*pmi=5;

Pointers To Member Functions

These consist of the member function's return type, the class name followed by ::, the pointer's name, and the function's parameter list. For example, a pointer to a member function of class A that returns an int and takes no arguments is defined as follows (note that both pairs of parentheses are mandatory):

class A { public: int func (); }; int (A::*pmf) ();

In other words, pmf is a pointer to a member function of class A that returns int and takes no arguments. In fact, a pointer to a member functions looks as an ordinary pointer to function, except that it also contains the class's name immediately followed by the :: operator. You can invoke the member function to which pmf points using operator .*:

pmf=&A::func; A a; (a.*pmf)(); /* invoke a.func() */

If you have a pointer to an object, you use the operator ->* instead:

A *pa=&a; (pa->*pmf)(); /*calls pa->func() */

Pointers to member functions respect polymorphism. Thus, if you call a virtual member function through such a pointer, the call will be resolved dynamically. Note, however, that you can't take the address of a class's constructor and destructor.