【问题标题】:Store a function c++, and call it later存储一个函数 c++,稍后调用
【发布时间】:2016-06-09 05:31:26
【问题描述】:

我正在开发一个应用程序,其中有很多小算法,每个算法都由几行代码表示,所以我想将那几行代码存储为函数,但不仅如此,我还必须存储每个算法具有的一些数据,所以我决定创建一个“算法”类,在其中,我将在“变量”中存储函数。所以,我可以稍后使用它。

我不知道这是否可行,或者是否有其他方法可以实现。 我认为我的“算法”所在的类的局部变量或私有成员会有问题。

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;
    }
}

只是一个小示例,我想将所有这些“addPoints()”行存储在一个函数中,并随时使用,像这样

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;
    }
}

编辑:这个问题包括使用库<functional>

【问题讨论】:

  • 我想你的答案就在这里:stackoverflow.com/questions/1485983/…
  • 你的意思是lambda functions
  • std::function, std::bind, lambda - 可能满足您的需求。
  • 使用可以使用 boost::functions 和 boost::bind。看看你要做的是创建一个 boost::function 类型的容器(向量、集合、队列等。根据你的要求适合)。用预期的功能初始化这个容器(在你的情况下是小算法)。然后使用只是迭代该容器并调用预期的函数。这是一种回调机制。

标签: c++ algorithm oop design-patterns optimization


【解决方案1】:

这听起来如何:

#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);
}

对于您的课程,您需要更改function 的模板参数的类型。

编辑(最小class 示例):

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();
}

但是,如果函数是全局的或静态的,则不需要做bind 的事情。

【讨论】:

  • (没有sound的描述,我只能检查它的外观。没有注释的代码,我倾向于不到。)
【解决方案2】:

使用 OOD 可以通过多种方式遇到问题。由于您有许多算法及其各自的数据,因此为此类算法创建类是有意义的。现在,就OOD而言,您可以使用Design Pattern : Strategy

是这样的:

为所有算法定义一个接口

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

现在,定义从接口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.*/);
};

现在定义这些算法的客户端。

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;
    }
};

现在根据需要可以有一个算法工厂

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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-12
    • 1970-01-01
    • 1970-01-01
    • 2021-09-19
    • 2017-08-04
    • 1970-01-01
    • 2014-06-05
    相关资源
    最近更新 更多