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

时间:2018-01-05 07:33:27

标签: c++ function-pointers

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

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

#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;
}

我打电话的班级:

 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);


 };

谢谢

1 个答案:

答案 0 :(得分:0)

首先,考虑使用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);
    }
};