关于带有签名void *数据的参数的非常基本的问题

时间:2011-09-28 22:54:13

标签: c++ pointers

这很可能是一个非常基本的问题 - 抱歉。

我在C ++中编写了一个由C引擎驱动的接口。其中一个C引擎函数具有以下特征:

static int f(double t, double *y, double *ydot, void *data)

*data是将用户数据传递给ODE求解器。现在,在C中,我只需创建一个struct,用我的数据初始化它,然后传递它。在C ++中,我想创建一个包含用户数据的类,并在我之前传递struct时传递它。这可以完成,因为structsclasses

然而,当我尝试这样做时,会发生以下情况:

int.cpp:25: error: no matching function for call to ‘UserData::UserData()’
int.cpp:13: note: candidates are: UserData::UserData(double)
int.cpp:5: note:                 UserData::UserData(const UserData&)
int.cpp:28: error: ‘void*’ is not a pointer-to-object type
int.cpp:29: error: ‘void*’ is not a pointer-to-object type

我的问题如下:

  1. void *data符号是什么意思?
  2. 为什么抱怨我没有带有相应签名的构造函数?
  3. 显然我是一个新手,所以我很抱歉,如果这是非常明显的,但我甚至不知道用什么术语来解决问题(除了谷歌搜索错误本身)。

    谢谢!

    编辑:

    我为上一个问题的模糊性道歉。此外,我解决了这个问题,这是一个非常愚蠢的错误。

    我有一个包含参数的类:

    class Data{
    // an interface to get parameters
    };
    

    我需要使用签名

    调用C函数
    static int f(double t, ...., void *user_data)
    

    我错误地这样做了:

    static int f(double t, ...., void *user_data){
     Data *data = (Data*) data; /* this is the stupid mistake */
    }
    

    当我打算这样做时(现在可行):

    static int f(double t, ...., void *user_data){
     Data *data = (Data*) user_data; /* this is the correction  */
    }
    

    谢谢大家 - 我非常感谢void *data的正确含义。

1 个答案:

答案 0 :(得分:3)

void *data 

表示指向任何地址的指针。它是一种传递任意类型数据的非类型安全方式。 C语言中的常见模式是实现C ++中function object的功能。数据参数可能实际上并非由您的ODE解算器使用,而是由您提供的回调。你和回调需要知道什么数据指向,ODE求解器不需要。解算器只是将地址传递给回调函数。

作为一个简单的例子,假设库具有在单个变量

中查找函数根的函数
  typedef double (*valuation_function) (double x, void * params);
  double find_root(valuation_function fn, double lower, double upper, void* params);

params函数使您能够编写参数化函数。假设你想找到一条线的根。

struct Line {
  double slope;
  double intercept;
  public:
     Line(double s, double i) : slope(s), intercept(i) {}
};

double a_line(double x, void *params) {
  Line* line = (Line *)params;
  return line->slope * x + line->intercept;
}

然后你可以为任何一行调用函数find_root。    Line fortyFive(1.0,0.0);    find_root(a_line,fortyFive);

您可以查看gsl库以获取更多examples