2016-06-09 78 views
1

我正在開發一個應用程序,其中有很多小算法,每個算法都由一些代碼行表示,所以我想將幾行代碼存儲爲函數,但不僅如此,我必須存儲每個算法所具有的一些數據,所以我決定創建一個「算法」類,其中,我將在一個「變量」中存儲函數。所以,我可以稍後使用它。保存一個函數C++,並在以後調用它

我不知道這是否可能,或者如果有另一種方法來達到這一點。 我認爲會有我的「算法」所在的類的局部變量或私有成員出現問題。

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>

+1

我認爲你的答案就在這裏:http://stackoverflow.com/questions/1485983/calling-c-class-methods-通過函數指針 –

+0

你的意思是[lambda函數](http://en.cppreference.com/w/cpp/language/lambda)? – tadman

+0

std :: function,std :: bind,lambda - 可能適合您的需求。 –

回答

3

請問這個聲音:

#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模板參數的類型。

EDIT(最小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事情。

+0

(沒有描述爲_sound_讀取,我只能檢查它的_looks_。沒有註釋的代碼,我傾向於不去。) – greybeard

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); 
相關問題