您好我正在尝试使用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
};
答案 0 :(得分: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[]);
};