1

I'm developing an app, in which I have a lot of small algorithms, each algorithm represented by some lines of code, so I want to store that few lines of code as functions, but not only that, I have to store some data that each algorithm has, so I decided to make a "Algorithm" class, in which, I would have in a "variable" the function stored. So, I can use it later.

I don't know if this is possible or if there is another way to reach that. I think there would be problems with local variables or private members of the class where my "algorithms" are.

class Patterns {

private:
    double line;
    double addPoint(char n) {line += n;}

public:
    double addPattern(int m) {
        double tmp = 0;
        char param;
        // some calculations with m

        // many calls to addPoint, "algorithm"
        tmp += addPoint(param); // param1
        tmp += addPoint(param); // param2
        tmp += addPoint(param); // param3
        tmp += addPoint(param); // param4

        return tmp;
    }
}

just a little sample, I want to store all those lines of "addPoints()" in only one function, and use whenever I want, something like this

class Patterns {

private:
    double line;
    double addPoint(char n) {line += n;}

public:
    double addPattern(int m) {
        double tmp = 0;
        // some calculations with m

        /**
         * vector of Algorithm class, get any Algorithm, and of that,
         * return the stored function, so I can use it as in the above sample
         */
        auto fn = vec->back()->getFunction();
        tmp += fn(m)

        return tmp;
    }
}

Edit: this question includes the use of the library <functional>

quetzalfir
  • 528
  • 7
  • 22
  • 1
    I think your answer is here: http://stackoverflow.com/questions/1485983/calling-c-class-methods-via-a-function-pointer – Alastair Brown Jun 09 '16 at 05:37
  • Do you mean [lambda functions](http://en.cppreference.com/w/cpp/language/lambda)? – tadman Jun 09 '16 at 05:46
  • std::function, std::bind, lambda - might fit your needs. – Jesper Juhl Jun 09 '16 at 05:58
  • Use can use boost::functions and boost::bind. See what you have to do is to create a container(vector, set, queue, etc.. suitable as per your requirement) of boost::function type. Initialize this container with the intended functions(in your case small small alogrithms). Then use just iterate over that container and call the intended function. This is a callback mechanism. – sagar Jun 09 '16 at 08:33

2 Answers2

3

How does this sound:

#include <vector>
#include <functional>

int test(int a)
{
    return a*2;
}
int main()
{
    using namespace  std;
    vector < function<int(int)>> fv;

    fv.push_back([](int a) {return a + 5; });

    (fv.back())(10);

    fv.push_back(test);

    (fv.back())(240);
}

For your class, you'd need to change the type of function's template argument.

EDIT (minimal class example):

class Pattern
{
    double addPoint(char n)
    {
        return n * 99.0;
    }
    double addPoint2(char n)
    {
        return n * 188.25;    
    }

    vector < function<double(char)>> funcs;
public:
    Pattern()
    {
        funcs.push_back(std::bind(&Pattern::addPoint, this, placeholders::_1));         
        funcs.push_back(std::bind(&Pattern::addPoint2, this, placeholders::_1));
    }

    void Call()
    {
        cout << (funcs.back())('A');
    }
};
int main()
{
    Pattern p;
    p.Call();
}

However, if the functions are global or static, you don't need to do bind thing.

Ajay
  • 18,086
  • 12
  • 59
  • 105
  • (Without a description to read for _sound_, I could only inspect it for what it _looks_. With uncommented code, I'm inclined not to.) – greybeard Jun 09 '16 at 17:08
2

There are multiple ways to encounter the problem using OOD. Since you have many algorithms along with their respective data then it makes sense to create classes for such algorithm. Now, as far as OOD is concerned then , you can use Design Pattern : Strategy.

It goes like this:

Define an interface for all you algorithm

class IAlgorithm
{
    public:
    virtual int Execute(/*external parameter list on which all algorithm depend.*/) = 0;        
};

Now, define different algorithms inheriting from interface IAlgorithm.

class CAlgorithm_Type1 : public IAlgorithm
{
    private:
        /* all the data members internally and exclusively used by this algorithm*/
    public:
        int Execute(/*external parameter list on which all algorithm depend.*/);
};

class CAlgorithm_Type2 : public IAlgorithm
{
    private:
        /* all the data members internally and exclusively used by this algorithm*/
    public:
        int Execute(/*external parameter list on which all algorithm depend.*/);
};

Now define the client of these algorithms.

class Patterns 
{
    private:
        double line;
        double addPoint(char n) {line += n;}
        IAlgorithm *m_pAlgorithm;

    public:
        SetAlgorithm(IAlgorithm *_pAlgorithm)
        {
            m_pAlgorithm = _pAlgorithm;
        }
        double addPattern(int m) {
        double tmp = 0;           

        tmp += m_pAlgorithm->Execute(m);

        return tmp;
    }
};

Now as per requirement there can be an Algorithm Factory

class ALGORITHM_LIBRARY
{
    public:
        enum TYPE
        {
            ALGORITHM_TYPE1,
            ALGORITHM_TYPE2,
            TOTAL_ALGORITHMS
        };

    ALGORITHM_LIBRARY()
    {
        m_Algorithms[ALGORITHM_LIBRARY::ALGORITHM_TYPE1] = new CAlgorithm_Type1();
        m_Algorithms[ALGORITHM_LIBRARY::ALGORITHM_TYPE2] = new CAlgorithm_Type2();
    }
    ~ALGORITHM_LIBRARY()
    {
        map<ALGORITHM_LIBRARY::TYPE, IAlgorithm*>::iterator it;
        for(it = m_Algorithms.begin(); it != m_Algorithms.end(); ++it)
        {
            delete it->second;
        }
    }
    IAlgorithm* GetAlgorithm(ALGORITHM_LIBRARY::TYPE _enumAlgorithmType)
    {
        return m_Algorithms[_enumAlgorithmType];
    }

    private:
        map<ALGORITHM_LIBRARY::TYPE, IAlgorithm*> m_Algorithms;
};


ALGORITHM_LIBRARY g_oAlgorithmLibrary;

enum enumAlgorithmType = ALGORITHM_LIBRARY::ALGORITHM_TYPE2;
Pattern Obj;
Obj.SetAlgorithm(g_oAlgorithmLibrary.GetAlgorithm(enumAlgorithmType));
Obj.addPattern(20);
sameerkn
  • 2,209
  • 1
  • 12
  • 13