Code Yarns ‍👨‍💻
Tech BlogPersonal Blog

C++: Function Pointers

📅 2010-Oct-25 ⬩ ✍️ Ashwin Nanjappa ⬩ 🏷️ cpp, functions, pointers ⬩ 📚 Archive

There are 2 kinds of pointers to class functions in C++:

  1. Pointer to static function of a class

  2. Pointer to (non-static) function of a class

Pointer to Static Function of a Class

For most practical purposes, the static function of a class behaves like a C-style function defined at the same scope of the class and which can be accessed by invoking the name of the class. Hence, a pointer to a static function is defined, assigned and invoked just like a C-style function pointer.

It is useful to first define a type of the pointer required:

typedef void ( *StaticFunctionPointer ) ( int );

The above type definition can be understood by reading outwards starting from the middle. It reads as "The type FooStaticFunctionPointer is a pointer to a function that takes an integer parameter and returns void". So, we have defined a pointer type that can point to any static function of any class with the above described signature.

After this, we can define a variable of the above type and initialize it by assigning the memory address of a function that matches the above signature:

class Foo
{
public:
    static void StaticFunc( int val )
    {}
};

StaticFunctionPointer statFp = &Foo::StaticFunc;

To invoke the function pointed to by this function pointer, use the indirection operator on the pointer:

(*statFp)( 10 );

Pointer to (Non-Static) Function of a Class

This pointer is a bit different in the invocation, but the definition and assignment is the same as that of static function. Note that this pointer will finally be invoked on a class object (and not a class).

The type definition and assignment of this function pointer is similar to that of static function pointer:

class Foo
{
public:
    void Func( int val )
    {}
};

typedef void ( Foo::* FooFunctionPointer ) ( int );

FooFunctionPointer fp = &Foo::Func;

To invoke a non-static function pointer, we need an object of the class which was used to initialize the function pointer. The invocation looks a bit more involved:

Foo foo;
(foo.*fp)( 30 );

Sample Code

Finally, here is code that illustrates both kinds of C++ function pointers:

#include <iostream>
using namespace std;

class Foo
{
public:

    // *** Static Functions

    static void StaticFunc0( int val )
    {
        cout << __FUNCTION__ << ": Value is " << val << endl;
    }

    static void StaticFunc1( int val )
    {
        cout << __FUNCTION__ << ": Value is " << val << endl;
    }

    // *** (Non-Static) Functions

    void Func0( int val )
    {
        cout << __FUNCTION__ << ": Value is " << val << endl;
    }

    void Func1( int val )
    {
        cout << __FUNCTION__ << ": Value is " << val << endl;
    }
};

// Pointer to a static function of a class
// The function has an integer parameter and returns void
typedef void ( *FooStaticFunctionPointer ) ( int );

// Pointer to a (non-static) function of a class
// The function has an integer parameter and returns void
typedef void ( Foo::* FooFunctionPointer ) ( int );

int main()
{
    // *** Static Function Pointer

    // Initialize the pointer
    FooStaticFunctionPointer statFp0 = &Foo::StaticFunc0;

    // Invoke the function pointed by pointer passing 10 as parameter
    (*statFp0)( 10 );

    // Same as above, but different static function
    FooStaticFunctionPointer statFp1 = &Foo::StaticFunc1;
    (*statFp1)( 20 );

    // *** (Non-Static) Function Pointer

    Foo foo; // Object of Foo class

    // Initialize the pointer to a function of Foo class
    FooFunctionPointer fp0 = &Foo::Func0;

    // Invoke the function pointed by pointer passing 30 as parameter
    (foo.*fp0)( 30 );

    // Same as above, but different function
    FooFunctionPointer fp1 = &Foo::Func1;
    (foo.*fp1)( 40 );

    return 0;
}