Expressions with Pointer-to-Member Operators

The pointer-to-member operators, .* and –>*, return the value of a specific class member for the object specified on the left side of the expression. The following example shows how to use these operators:

#include <iostream.h>

class Window
{
public:
    void Paint(); // Causes window to repaint.
    int WindowId;
};

// Define derived types pmfnPaint and pmWindowId.
// These types are pointers to members Paint() and
// WindowId, respectively.
void (Window::*pmfnPaint)() = &Window::Paint;
int Window::*pmWindowId = &Window::WindowId;

void main()
{
    Window AWindow;
    Window *pWindow = new Window;
// Invoke the Paint function normally, then use pointer to member.
    AWindow.Paint();
    (AWindow.*pmfnPaint)();

    pWindow->Paint();
    (pWindow->*pmfnPaint)(); // Parentheses required since * binds
                             //  less tightly than the function call.

    int Id;
    // Retrieve window id.
    Id = AWindow.*pmWindowId;
    Id = pWindow->*pmWindowId;
}

In the preceding example, a pointer to a member, pmfnPaint, is used to invoke the member function Paint. Another pointer to a member, pmWindowId, is used to access the WindowId member.

Syntax

pm-expression :

cast-expression
pm-expression .* cast-expression
pm-expression –>* cast-expression

The binary operator .* combines its first operand, which must be an object of class type, with its second operand, which must be a pointer-to-member type.

The binary operator –>* combines its first operand, which must be a pointer to an object of class type, with its second operand, which must be a pointer-to-member type.

In an expression containing the .* operator, the first operand must be of the class type of, and be accessible to, the pointer to member specified in the second operand or of an accessible type unambiguously derived from and accessible to that class.

In an expression containing the –>* operator, the first operand must be of the type “pointer to the class type” of the type specified in the second operand, or it must be of a type unambiguously derived from that class.

Consider the following classes and program fragment:

class BaseClass
{
public:
    BaseClass(); // Base class constructor.
    void Func1();
};

// Declare a pointer to member function Func1.
void (BaseClass::*pmfnFunc1)() = &BaseClass::Func1;

class Derived : public BaseClass
{
public:
    Derived();  // Derived class constructor.
    void Func2();
};

// Declare a pointer to member function Func2.
void (Derived::*pmfnFunc2)() = &Derived::Func2;

void main()
{
    BaseClass ABase;
    Derived ADerived;

    (ABase.*pmfnFunc1)();    // OK: defined for BaseClass.
    (ABase.*pmfnFunc2)();    // Error: cannot use base class to
                             //  access pointers to members of
                             //  derived classes. 
    (ADerived.*pmfnFunc1)(); // OK: Derived is unambiguously
                             //  derived from BaseClass. 
    (ADerived.*pmfnFunc2)(); // OK: defined for Derived.
}

The result of the .* or –>* pointer-to-member operators is an object or function of the type specified in the declaration of the pointer to member. So, in the preceding example, the result of the expression ADerived.*pmfnFunc1() is a pointer to a function that returns void. This result is an l-value if the second operand is an l-value.

Note   If the result of one of the pointer-to-member operators is a function, then the result can be used only as an operand to the function call operator.