重构 C++,"no matching function to call"

Refactoring C++, "no matching function to call"

我正在学习如何有效地分离我的 ESP8266 项目的 C++ 代码,我 运行 遇到了提取网络服务器功能和 objects 的一些问题。我使用 this 教程中的示例代码作为我的基础。

我觉得我正在了解如何构建 class 和 header 的基础知识,但是当我尝试在我的 class 中使用另一个 class 时,我出现错误...但仅限于部分功能。

这是我的 main.cpp:

#include <CServer.h>

CServer clientServer(80); //create a CServer, which will create a private WebServer object on init.

void setup(void)
{     
  clientServer.startRoutes(); //start routes declared in CServer.cpp
  clientServer.begin(); // start the server
} 

void loop(void){
  clientServer.handleClient();                    // Listen for HTTP requests from clients
}

这是我的 CServer.h:

//begin include for class CServer to handle client server functions
#ifndef CSERVER_H
#define CSERVER_H

#include <ESP8266WebServer.h>
//Client server functions are handled by this class.
ESP8266WebServer
class CServer
{
private:
  ESP8266WebServer server; //local instance of the webserver object
public:
  CServer(int port);

  void handleClient();
  void handleNotFound();
  void handleRoot();
  void begin();
  void startRoutes();
};

#endif

最后 CServer.cpp

#include "CServer.h"

CServer::CServer(int port)
{
  ESP8266WebServer server(port); //create a server with the passed port
}

void CServer::handleClient()
{
  server.handleClient();
};

void CServer::handleRoot()
{
  server.send(200, "text/plain", "Hello world!"); // Send HTTP status 200 (Ok) and send some text to the browser/client
}

void CServer::handleNotFound()
{
  server.send(404, "text/plain", "404: Not found"); // Send HTTP status 404 (Not Found) when there's no handler for the URI in the request
}

void CServer::begin()
{
  server.begin();
}

void CServer::startRoutes()
{
  server.on("/", handleRoot);
  server.onNotFound(handleNotFound);
}

我遇到错误:

no matching function for call to 'esp8266webserver::ESP8266WebServerTemplate::on(const char [2], )'

对于 handleRoot 和 handleNotFound 函数,我试图传递给 .cpp 文件末尾的 "server.on" 和 "server.onNotFound"。

我想用许多不同的库来做这种事情来构建一个设备,我真的很想知道如何用这个策略有效地清理我的代码,所以理解正确的方法是至关重要的.

您正试图将一个非静态成员函数传递给 server.on("/", handleRoot);,它需要一个签名为 void() 的可调用函数(即一个可以在没有任何参数的情况下调用并返回 void).

然而,非静态成员函数不是不带任何参数的可调用函数。它至少需要一个参数,即指向 class 实例的隐式 this 指针。

如果您希望处理程序在调用 startRoutes 的当前 class 实例上调用 handleRoot,则使用 lambda 调用成员并捕获 this:

server.on("/", [this]{ handleRoot(); });

正如@Peter 在问题评论中提到的,您也没有正确初始化 server 成员。相反,您正在创建 ESP8266WebServer 的本地实例,也称为 server,但它是构造函数的本地实例,并在构造函数离开时销毁。此实例与 class 成员实例无关,只是它们共享类型和名称。

如果你想用 port 作为参数初始化 server 成员,你可以在构造函数的 成员初始化列表 中进行:

CServer::CServer(int port) : server(port)
{
}