Thursday, June 2, 2011

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 member functions 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.

No comments:

Post a Comment