在 C++ 中将函数作为参数传递

passing function as argument in c++

我正在尝试将函数作为参数传递,Testabc 继承自 MainTest,而我要传递的函数是 MainTest 中的受保护函数 class。我没有对具有此受保护 ReadTestPoint 函数的 MainTest class 的 cpp 访问权限。

下面是头文件,我在其中定义了将函数作为参数的函数。

#include <QObject>
#include <QDebug>

class TestManager
{
 public:
 TestManager();
~TestManager() {}
int ReadTestPointer(void *dp, unsigned int &val, int (*functioncall)(void *, 
unsigned int&));
};

下面是 TestManager

的 cpp
#include "testmanager.h"
#include<QDebug>
TestManager::TestManager(){}

int TestManager::ReadTestPointer(void* dp, unsigned int &num, int (*readt)
(void*, unsigned int&))
{
   qDebug()<< "Function Pointer working";
   int g;
   g = (*readt)(dp, num);
   return g;
}

我拨打电话的class:

 namespace PackageCore
 {

 TestAbc::TestAbc() : MainTest(){}
 TestAbc::~TestAbc(){}

 int TestAbc::Init()
 {
  // initialization code called once
   m_config = reinterpret_cast<Test_BaseClass*>
   (GetConfig(Test_BaseClass_INTERFACE_HASH));
  return 0;
}
int TestAbc::DeInit()
{
   return 0;
}

int TestAbc::Cycle()
{
   TestManager m_TestManager;
   unsigned int m_trigger;
   int (*abc)(void *, unsigned int&) = ReadTestPoint(m_config-
    >SHM_B_Trigger_U8, m_trigger);
   m_TestManager.ReadTestPointer(m_config->SHM_B_Trigger_U8, m_trigger, abc);
   qDebug()<< " getTrigger: " << m_trigger;
   return 0;
}
}

但是我得到编译时错误:

C:\test_manager_git\testabc.cpp:39: error: invalid conversion from 'int' to 'int (*)(void*, unsigned int&)' [-fpermissive]
 int (*abc)(void *, unsigned int&) = ReadTestPoint(m_config->SHM_B_Trigger_U8, m_trigger);
                                                                                            The MainTest.h is below:
   class MainTest : public QObject
  {
   Q_OBJECT

   public:

    // Callbacks
    virtual int Init() = 0;
    virtual int Cycle() = 0;
    virtual int DeInit() = 0;

   protected:


     int ReadTestPoint (void *dp, unsigned int &val);


 };

谢谢

首先,考虑使用 std::function 之类的东西,而不是滚动你自己的指针噩梦。但是让我们开始吧...

基本上,为了从指针调用成员函数,您需要函数指针和成员实例。以下代码是根据你的问题代码加上成员指针。

#include <iostream>


class MainTest
{
public:

protected:
    int ReadTestPoint (void *dp, unsigned int &val)
    {
        std::cout << "protected ReadTestPoint called" << std::endl;
        return 0;
    }
};



class TestManager
{
public:
    TestManager() {}
    ~TestManager() {}
    int ReadTestPointer(void *dp, unsigned int &val, MainTest* instance, int (MainTest::*functioncall)(void *, unsigned int&))
    {
        return (instance->*functioncall)(dp, val);
    }
};


class TestAbc : public MainTest
{
public:
    void ExecTest()
    {
        TestManager testManager;
        unsigned int tVal;
        void* dummy = &tVal;

        testManager.ReadTestPointer(dummy, tVal, this, &TestAbc::ReadTestPoint);
    }
};


int main(void)
{
    TestAbc test;
    test.ExecTest();

    return 0;
}

如果您不想将自己局限于特定的成员类型,请考虑使用模板函数:

class TestManager
{
public:
    TestManager() {}
    ~TestManager() {}

    template<typename Fn>
    int ReadTestPointer(void *dp, unsigned int &val, Fn functioncall)
    {
        return functioncall(dp, val);
    }
};

它将接受使用适当的参数和 return 类型重载 operator() 的非成员函数和对象。

您可以将成员函数指针包装在一个 Functor 对象中:

template<typename TMember, typename TResult, typename TParam1, typename TParam2>
struct Functor
{
    typedef TResult (TMember::*TFn)(TParam1, TParam2);

    Functor(TMember* m, TFn func):member(m), fn(func){}

    TMember* member;
    TFn fn;

    TResult operator()(TParam1 p1, TParam2 p2)
    {
        return (member->*fn)(p1, p2);
    }
};

下面的例子包括一个自由函数调用和一个成员函数调用:

int FreeFn(void *dp, unsigned int &val)
{
    std::cout << "free function called" << std::endl;
    return 1;
}


class TestAbc : public MainTest
{
public:
    void ExecTest()
    {
        TestManager testManager;
        unsigned int tVal;
        void* dummy = &tVal;

        testManager.ReadTestPointer(dummy, tVal, Functor<TestAbc, int, void*, unsigned int&>(this, &TestAbc::ReadTestPoint));

        testManager.ReadTestPointer(dummy, tVal, FreeFn);
    }
};