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

passing function as argument in c++

本文关键字:参数传递 函数 C++      更新时间:2023-10-16

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

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

#include <QObject>
#include <QDebug>
class TestManager
{
 public:
 TestManager();
~TestManager() {}
int ReadTestPointer(void *dp, unsigned int &val, int (*functioncall)(void *, 
unsigned int&));
};

下面是测试管理器的 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;
}

我打电话的班级:

 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_gittestabc.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);
    }
};

它将接受使用适当的参数和返回类型重载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);
    }
};