我是C ++的新手,我无法使用指向成员函数的指针函数。我正在ESP8266上使用PlatformIO进行编程。
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);
};
UdpTask.cpp
UdpTask::UdpTask(String(*handleGson)(String)) {
this->handleGson = handleGson;
}
GsonHandler.h
class GsonHandler {
public:
String handleGson(String gson);
};
GsonHandler.cpp
String GsonHandler::handleGson(String gson) {
return ":)";
}
main.cpp
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));
构造函数期望的参数不是指向成员函数的指针。相反,它是指向free函数的指针。指向成员函数的指针的形式应为:
String (GsonHandler::*)(String)
请注意,指向member的指针需要知道它是什么类型的成员。
关于您的原始问题-有多种解决方法(与C ++一样)。>>
最简单的方法是使用std::function<String(String)>
存储functor
。那就是任何可以被调用的对象。所以something
class UdpTask : public Task { public: UdpTask(std::function<String(String)> f); private: ... std::function<String(String)> handler; };
在实现中,您仅将其称为:
handler(args);
如果无法使用std
功能-可以探索其他解决方案。
最简单的方法是在您的UdpTask
中存储指向处理程序的指针,然后直接调用其方法:
class UdpTask : public Task { public: UdpTask(GsonHandler* handler); private: ... GsonHandler* handler; };
在实现中,您仅将其称为:
handler->handleGson(args);
[现在,我确实意识到,UdpTask
与有效地是UDP data handler
之间可能存在紧密的联系。因此,您可以考虑为DataHandler创建通用接口,存储指向它的指针,并使GsonHandler
实现DataHandler
的实现:
struct DataHandler {
virtual ~DataHandler() = default;
virtual String handleData(String data) = 0;
};
struct GsonHandler: public DataHandler {
String handleData(String data) override;
...
};
...
class UdpTask : public Task {
public:
UdpTask(DataHandler* handler);
private:
...
DataHandler* handler;
};