指向成员函数C++; 我是C++新手,我对指针函数和成员函数有问题。我正在ESP8266上使用PlatformIO编程

指向成员函数C++; 我是C++新手,我对指针函数和成员函数有问题。我正在ESP8266上使用PlatformIO编程,c++,function-pointers,esp8266,member-function-pointers,C++,Function Pointers,Esp8266,Member Function Pointers,UdpTask.h class UdpTask : public Task { public: void setup(); void loop(); UdpTask(String (*handleGson)(String)); private: char replyPacket[]; char incomingPacket[UDP_TX_PACKET_MAX_SIZE]; unsigned int localUdpPort; WiF

UdpTask.h

class UdpTask : public Task {
  public:
    void setup();
    void loop();
    UdpTask(String (*handleGson)(String));
  private:
    char replyPacket[];
    char incomingPacket[UDP_TX_PACKET_MAX_SIZE];
    unsigned int localUdpPort;
    WiFiUDP Udp;
    String (*handleGson)(String);
};
class GsonHandler {
  public:
    String handleGson(String gson);
}; 
UdpTask.cpp

UdpTask::UdpTask(String(*handleGson)(String)) {
  this->handleGson = handleGson; 
}
String GsonHandler::handleGson(String gson) {
  return ":)";
}
GsonHandler gsonHandler;
UdpTask udpTask(&gsonHandler.handleGson);
GsonHandler.h

class UdpTask : public Task {
  public:
    void setup();
    void loop();
    UdpTask(String (*handleGson)(String));
  private:
    char replyPacket[];
    char incomingPacket[UDP_TX_PACKET_MAX_SIZE];
    unsigned int localUdpPort;
    WiFiUDP Udp;
    String (*handleGson)(String);
};
class GsonHandler {
  public:
    String handleGson(String gson);
}; 
GsonHandler.cpp

UdpTask::UdpTask(String(*handleGson)(String)) {
  this->handleGson = handleGson; 
}
String GsonHandler::handleGson(String gson) {
  return ":)";
}
GsonHandler gsonHandler;
UdpTask udpTask(&gsonHandler.handleGson);
main.cpp

UdpTask::UdpTask(String(*handleGson)(String)) {
  this->handleGson = handleGson; 
}
String GsonHandler::handleGson(String gson) {
  return ":)";
}
GsonHandler gsonHandler;
UdpTask udpTask(&gsonHandler.handleGson);
错误:

src\main.cpp:16:30: error: ISO C++ forbids taking the address of a bound member function to form a pointer to member function.  Say '&GsonHandler::handleGson' [-fpermissive]
 UdpTask udpTask(&gsonHandler.handleGson);
                              ^
src\main.cpp:16:40: error: no matching function for call to 'UdpTask::UdpTask(String (GsonHandler::*)(String))'
 UdpTask udpTask(&gsonHandler.handleGson);
注意: 我已经尝试了错误消息中的建议,但是我找不到一种方法让它工作…,而且,我知道在这个简单的例子中,它可以更容易地解决,例如只传递整个对象,但是我需要这种指针,在这种方法更容易的地方


提前感谢。

正如评论中已经指出的那样,
UdpTask(String(*handleGson)(String))构造函数期望的不是指向成员函数的指针。相反,它是指向自由函数的指针。指向成员函数的指针的形式如下:

String (GsonHandler::*)(String) 
请注意,指向成员的指针需要知道成员的类型

至于您最初的问题,有很多方法可以解决它(就像C++一样)

最简单的方法是使用
std::function
存储
functor
。这是任何可以调用的对象。比如:

class-UdpTask:公共任务{
公众:
UdpTask(std::函数f);
私人:
...
函数处理程序;
};
在实现中,您只需将其称为:
handler(args)

如果您不能使用
std
函数,可以探索其他解决方案

最简单的方法是将指向处理程序的指针存储在
UdpTask
中,并直接调用其方法:

class-UdpTask:公共任务{
公众:
UdpTask(GsonHandler*handler);
私人:
...
GsonHandler*handler;
};
在实现中,您只需将其称为:
handler->handleGson(args)

现在,我确实认识到,
UdpTask
和基本上是一个
UDP数据处理程序
之间可能存在紧密耦合的潜在问题。 因此,您可以考虑为DataHandler创建通用接口,存储指向它的指针,并将
GsonHandler
作为
DataHandler
的实现:

结构数据处理程序{ virtual~DataHandler()=默认值; 虚拟字符串句柄数据(字符串数据)=0; }; 结构GsonHandler:公共数据处理程序{ 字符串句柄数据(字符串数据)覆盖; ... }; ... 类UdpTask:公共任务{ 公众: UdpTask(DataHandler*handler); 私人: ... DataHandler*处理器; };
能否
GsonHandler::handleGson
静态的
?不能将指向非静态成员函数的指针当作指向普通函数的指针来使用。这些基本上是不相容的。如果
static
不是一个对象,您可能应该保存一个
std::function
。是否尝试使用闭包?(即,一个对象及其成员函数)。指向成员的指针与任何特定对象都没有关联这正是我一直在搜索的内容,非常感谢。是的,这是一种简单的方法。它对于一个对C++ STL库的支持有限的平台可能不起作用。不知道ESP8266的详细信息。你能评论一下它的std::function是否适合你吗?