GSL中的静态虚拟变通方法

gpi*_*ris 4 c++ virtual static

您好我正在尝试使用GNU Scientific Library中的微分方程包编写一个小程序来模拟动态系统.问题不是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
};
Run Code Online (Sandbox Code Playgroud)

Dar*_*con 6

我假设void*你的函数定义中是一个用户指定的回调参数.在这种情况下,使用此参数将指针传递给对象,并使回调成为静态函数.在此静态函数内,将此指针强制转换为正确的type(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[]);
};
Run Code Online (Sandbox Code Playgroud)