2012-05-21 23 views
4

您好,我正在嘗試編寫一個小程序來模擬GNU科學庫中使用微分方程包的動態系統。問題不是特定於GSL,但我只是給你所有的細節GSL中的靜態虛擬解決方法

在當前的設計中,我想要一個抽象的Experiment類,其中所有複雜的函數將由gsl庫調用。顯式系統的動力學將由兩個函數定義,即func和jacob,分別定義特定的運動方程和雅可比行列式。因此,我想在Experiment類中執行所有的模擬,並且只覆蓋具有將由Experiment繼承的特定類的兩個虛擬函數。

我的問題是,由於虛擬的這些方法不編譯

error: argument of type ‘int (Experiment::)(double, const double*, double*, void*)’ does not match ‘int (*)(double, const double*, double*, void*)’

如果我讓這兩個功能的靜態程序編譯,但我失去的是我想達到的具體問題的功能。

顯然,它們不能同時是靜態的和虛擬的,所以有人知道這個問題的解決方法嗎?有沒有更好的方法來處理它?

在此先感謝。

編輯:下面編譯代碼,但他們不是虛擬

class Experiment 
{ 
public: 
    Experiment(); 
    ~Experiment(); 

    void setupExperiment(); 
    static int func(double t, const double y[], double f[], void *params); 
    static int jac (double t, const double y[], double *dfdy, double dfdt[], void *params); 
}; 

void Experiment::setupExperiment(){ 

    double mu = 10; 

    gsl_odeiv2_system sys = {func, jac, 2, &mu}; //Here is the problem with virtual functions 
} 

class aSpecificProblem: public Experiment{ 

    // I want to implement just the func and jac function which should be virtual above 
}; 

回答

6

我相信在你的函數定義的void*是用戶指定的回調參數。在這種情況下,使用此參數將指針傳遞給對象,並使您的回調成爲靜態函數。在此靜態函數內部,將此指針轉換回適當的類型(Experiment*)並調用該函數的非靜態版本。

class Experiment 
{ 
public: 
    Experiment(); 
    ~Experiment(); 

    void setupExperiment(); 
    static int static_func(double t, const double y[], double f[], void *params); 
    static int static_jac (double t, const double y[], double *dfdy, double dfdt[], void *params); 
    virtual int func(double t, const double y[], double f[]); 
    virtual int jac (double t, const double y[], double *dfdy, double dfdt[]); 
}; 

void Experiment::setupExperiment() 
{ 
    gsl_odeiv2_system sys = {static_func, static_jac, 2, this}; //Here is the problem with virtual functions 
} 

int Experiment::static_func(double t, const double y[], double f[], void *params) 
{ 
    return ((Experiment*)params)->func(t, y, f); 
} 

int Experiment::static_jac (double t, const double y[], double *dfdy, double dfdt[], void *params) 
{ 
    return ((Experiment*)params)->jac(t, y, dfdy, dfdt); 
} 

class aSpecificProblem: public Experiment 
{ 
public: 
    virtual int func(double t, const double y[], double f[]); 
    virtual int jac (double t, const double y[], double *dfdy, double dfdt[]); 
}; 
+0

感謝您付出的努力。它看起來像一個解決方案,我現在要去測試它。再次感謝! – gpierris