c ++指向非静态成员函数的指针

时间:2017-07-26 15:57:17

标签: c++ function-pointers non-static

我已经阅读了许多关于非静态成员函数指针的帖子和答案,但没有一个看起来能够解决我的问题。
所以我在这里创建了一个简短的例子来复制我的问题:即使这个例子可以以不同的方式“解决”,对于最终的软件,保持结构就像在例子中一样重要,谢谢。

这是“Funcs.h”类的标题:

#include "Funcs.h"

using namespace std;

Funcs::Funcs()
{
}

Funcs::~Funcs()
{
}

double Funcs::Fun1(double X) {
  double f1 = a*X;

  return f1;
}

double Funcs::solver(double X0)
{
  double result;

  result = aaa(Fun1, X0);
  return result;
}

double Funcs::aaa(double(*fun)(double), double x0)
{
  return fun(x0);
}

这是“Funcs.cpp”类的cpp:

#include <iostream>
#include "Funcs.h"

using namespace std;

int main() {
  double x0=1;
  double result;
  Funcs funcs;

  result = funcs.solver(x0);
  cout << result << endl;

  return 0;
}

最后这是主要的“main.cpp”:

{{1}}

当我调用“result = aaa(Fun1,X0);”时,错误发生在方法Funcs :: solver中。因为我不能使用指向Fun1的指针,因为它是一个非静态成员。同时我不能使它静止,否则在静态方法中看不到变量“a”。

提前感谢您的帮助。

4 个答案:

答案 0 :(得分:6)

问题是您正在尝试将指针传递给成员函数,而指向非成员函数或静态成员函数的指针是预期的。那些是不同的类型。

这里“fun”是指向函数的指针:double(*fun)(double)

这里是指向类Funcs的成员函数的指针:double(Funcs::*fun)(double)

因此,您可以修改代码以使其正常工作。

class Funcs
{
  // all the rest is the same
  double aaa(double(Funcs::*fun)(double), double x0);
};

double Funcs::solver(double X0)
{
  // ...
  result = aaa(&Funcs::Fun1, X0);
  // ...
}

double Funcs::aaa(double(Funcs::*fun)(double), double x0)
{
  return (this->*fun)(x0);
}

查看实时示例at Coliru

如果您想故意限制方法aaa仅接受Funcs成员函数fun,这可能是一个很好的方法。如果您还想传递非会员功能,或者例如lambdas到aaa,请考虑使用std::function

答案 1 :(得分:4)

你的问题是指向函数的指针与指向成员函数的指针不同。阅读this以获取更多信息,阅读this以获得编写指向成员函数的指针的简洁方法。如果您需要保留此结构,请将aaa设置为静态或非成员函数,将其需要的所有内容作为参数,或者将aaa的第一个参数更改为double(Funcs::*)(double)而不是double(*fun)(double)。您甚至可以重载aaa以支持两种用途。

答案 2 :(得分:2)

实际上Funcs::Fun1不是double(*)(double)

任何非静态方法都有此签名:return_type(*)(class_type* this, arguments...)

让我们看一下确切的类型:

//first argument of `aaa` has type double(*)(double)
double aaa(double(*fun)(double), double x0);

double Funcs::Fun1(double X) {
  double f1 = a*X;

  return f1;
}

// Fun1 has type double(Funs::*)(double)
// i.e it's a method of Funs and it takes (implicitly) first argument
// which is `this` pointer

// so that how `aaa` must  look like
double aaa(double(Funs::*fun)(double), double x0)
{
    // special sytax
    *this.*fun(x0);
}

// and that how `solver` looks like
double Funcs::solver(double X0)
{
  double result;

  // get pointer to method
  result = aaa(&Funs::Fun1, X0);
  return result;
}

如果您不熟悉方法指针 - 请查看this

答案 3 :(得分:0)

我对c ++还是陌生的,但是我知道的解决方案是让静态函数充当委托。 https://docs.microsoft.com/ru-ru/windows/win32/learnwin32/managing-application-state-

////按照全代码链接了解我在说什么:)

看看win32 API如何提供充当委托的静态回调函数。简而言之,函数接受输入的数量,最后一个参数是调用者作为空指针传递的类。

static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
    {
        DERIVED_TYPE *pThis = NULL;

        if (uMsg == WM_NCCREATE)
        {
            // routine to recast back pointer to your class type so you have access to your local members with "This"
            CREATESTRUCT* pCreate = (CREATESTRUCT*)lParam;  
            pThis = (DERIVED_TYPE*)pCreate->lpCreateParams;
            SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis);

            pThis->m_hwnd = hwnd;
        }

看看lParam是如何被强制转换回DERIVED_TYPE的,这是您的类的一种,而pThis就像正常情况一样,可以访问类成员。