In this article we will discuss, what is a Function Object, why do we need function objects and how to use function objects as Callbacks.

What is a Function Objects:

A Function Object / Functor is a kind of Callback with State.

In a Programmer’s terminology,

Object of a class which has overloaded operator() is called Function Object or Functor i.e. a class with overloaded operator() function is as follows,

Now lets create a function object and call them,

Function objects / Functors can be called just like normal functions i.e.

is similar to following code,

Let’s understand by a practice example,

In previous article we discussed how to use function pointer call back to change the behaviour of message builder API. Checkout the article here,

Designing Callbacks with Function Pointers in C++

Let’s refresh the problem statement,

From a framework we got an API that can build complete message from provided raw data. This API will perform following steps,

1.) Add header and footer in raw Data to make the message.
2.) Encrypt the complete message.
3.) Return the message

 

Now this API knows what header and footer to apply but don’t know about exact encryption logic, because that is not fixed to Framework, that can change from application to application.
As, Encryption Logic is application dependent, therefore it provides a provision to pass encryption logic as a callback function pointer,

No suppose in our application we want to call this framework API three times with 3 different types of encryption logics i.e.

Encrypt by incrementing each letter by 1.
Encrypt by incrementing each letter by 2.
Encrypt by decrementing each letter by 1.

How to this through function pointers,

For this we need to create three different types of functions and use them as function pointers while calling this API.
3 different functions here are necessary because normal global functions don’t have any state associated with them,

Is there any way to bind state with function pointers?

Answers is yes –  By making the them function objects or functors.

Let’s create a Function Object / Functor for Encryption:

A function object or functor, is an object that has operator () defined as member function i.e.

These function objects can be called just like functions in message builder API.

What just happened here is a temporary object of EncruptFunctor is created and operator () is called on it.

It can also be called like,

It similar to calling,

Now use this function object two solve our problem. Create a function object that can encrypt by decementing / increment each letter by specified number of times.

So, this is how we can use function objects as callbacks.

Complete executable code is as follows,

#include <iostream>

class Encryptor {
    bool m_isIncremental;
    int m_count;
public:
    Encryptor() {
        m_isIncremental = 0;
        m_count = 1;
    }
    Encryptor(bool isInc, int count) {
        m_isIncremental = isInc;
        m_count = count;
    }
    std::string operator()(std::string data) {
        for (int i = 0; i < data.size(); i++)
            if ((data[i] >= 'a' && data[i] <= 'z')
                    || (data[i] >= 'A' && data[i] <= 'Z'))
                if (m_isIncremental)
                    data[i] = data[i] + m_count;
                else
                    data[i] = data[i] - m_count;
        return data;
    }

};

std::string buildCompleteMessage(std::string rawData,
        Encryptor encyptorFuncObj) {
    // Add some header and footer to data to make it complete message
    rawData = "[HEADER]" + rawData + "[FooTER]";

    // Call the callBack provided i.e. function pointer to encrypt the
    rawData = encyptorFuncObj(rawData);

    return rawData;
}

int main() {
    std::string msg = buildCompleteMessage("SampleString", Encryptor(true, 1));
    std::cout << msg << std::endl;

    msg = buildCompleteMessage("SampleString", Encryptor(true, 2));
    std::cout << msg << std::endl;

    msg = buildCompleteMessage("SampleString", Encryptor(false, 1));
    std::cout << msg << std::endl;

    return 0;
}

Click Here to Subscribe for more Articles / Tutorials like this.