常量函数指针

4

我在函数指针方面遇到了一些困难。我有一个基类,它定义了一个函数指针,通过 typedef double (*function)(double *x) const;

  • 一个快速的侧面问题:为什么上面的 typedef 无法编译?

    会出现以下错误:error: ‘const’ and ‘volatile’ function specifiers on ‘function’ invalid in type declaration

对于下面的部分,我使用 typedef double (*function)(double *x)。现在每个子类都可以实现多个不同版本的此类型的函数。通过枚举,我选择我的选择功能,这将使我的非成员函数指针(在基类中定义)被初始化为其中一个子类的成员函数指针之一。这是一个代码片段:

女儿类的源文件:

PndLmdROOTDataModel1D::PndLmdROOTDataModel1D(interpolation_type intpol_type) {
  if(intpol_type == CONSTANT) {
    setModelFunction(&PndLmdROOTDataModel1D::evaluateConstant); 
  }
  else if (intpol_type == SPLINE) {
    setModelFunction(&PndLmdROOTDataModel1D::evaluateSpline);
  }
  else {
    setModelFunction(&PndLmdROOTDataModel1D::evaluateLinear);
  }
}

同时,基类(头文件)如下:

class MultiModel1D: public Model1D {
protected:
  function model_func;

public:
  MultiModel1D();
  virtual ~MultiModel1D();

  void setModelFunction(function f);
}

编译时我遇到了如下错误:
注意: 参数1的类型为'double(PndLmdROOTDataModel1D::*)(double*)',但实际上需要的是'function {aka double(*)(double*)}'
我正在使用函数指针,因为速度问题(至少我认为这比不断运行某些开关情况要快)。我做错了什么?也许还有一些设计模式可以作为更好的替代方案...提前感谢!
史蒂夫

底部的错误已经说明了一切。函数指针与成员函数指针不同。http://liveworkspace.org/code/1iUxos%242 - chris
普通函数不能是 const 吗? - yngccc
我感到困惑,你的问题是哪一个比特?你似乎有几个问题。 - Lightness Races in Orbit
就像成员函数不同于函数一样(记住,成员函数有一个“隐藏”的this参数),成员函数指针也不同于函数指针。你正在试图将成员函数指针塞入函数指针中。 - Nik Bougalis
const部分已经明白了,谢谢!但是为什么我不能将成员函数指针转换为非成员函数指针呢?编译器为什么要在意这个?我可以看到他说它们不一样...那么这是否意味着我想做的事情根本不可能实现,还是有解决方案?在typedef中将函数指针设置为成员函数指针似乎没有帮助,因为我有几个派生类。因此,一个成员函数指针将由另一种类型初始化。 - steve
2个回答

16

那是因为自由函数指针和成员函数指针之间存在根本区别。你的“侧面问题”已经包含了解决问题的提示。为了解释清楚,你可以这样做:

typedef double (SomeClass::*function)(double *x) const;
或者
typedef double (*function)(double *x);

但是非成员函数无法在函数级别上声明为const。这些类型不能相互转换,这就是编译器指出的代码问题所在。

如果它们能够被转换,你最终会遇到问题:成员函数指针告诉编译器需要一个对象才能调用,该对象将在调用成员函数时放入this中。如果指针可以转换为普通函数指针,那么这个对象将不存在,可能所有参数都会受到影响而混乱。所以,不,你真的不能只是强制转换它们。现实情况更加复杂(多重/虚拟继承),但你明白了......


感谢超快的回答!我现在懂得非成员函数中的const部分毫无意义了。但是对于第二个错误,我把所有的const都去掉了。我的问题基本上是为什么编译器不能将成员函数指针转换为非成员函数指针。 - steve
@steve:我添加了一份说明。 - Daniel Frey

8

出于同样的原因,我们也不应该这样写:

void foo() const
{
   // ...
}

类声明之外的非成员函数不能是const

您的函数指针是普通函数指针,而不是指向成员函数的指针,因此const在这里没有意义。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接