Pointers to Members and Virtual Functions

Invoking a virtual function through a pointer-to-member function works as if the function had been called directly: the correct function is looked up in the v-table and invoked. The following code shows how this is done:

class Base
{
public:
    virtual void Print();
};
void (Base ::* bfnPrint)() = &Base :: Print;

void Base :: Print()
{
    cout << "Print function for class 'Base'\n";
}

class Derived : public Base
{
public:
    void Print();  // Print is still a virtual function.
};

void Derived :: Print()
{
    cout << "Print function for class 'Derived'\n";
}

void main()
{
    Base   *bPtr;
    Base    bObject;
    Derived dObject;

    bPtr = &bObject;    // Set pointer to address of bObject.
    (bPtr->*bfnPrint)();

    bPtr = &dObject;    // Set pointer to address of dObject.
    (bPtr->*bfnPrint)();
}

The output from this program is:

Print function for class 'Base'
Print function for class 'Derived'

The key to virtual functions working, as always, is invoking them through a pointer to a base class. (For more information about virtual functions, see Virtual Functions in Chapter 9.)