重构C ++,“没有匹配的函数要调用”

时间:2019-12-30 03:12:43

标签: c++ arduino refactoring esp8266

我正在研究如何有效地为ESP8266项目分离我的C ++代码,并且在拔出Web服务器功能和对象时遇到了一些问题。我将this教程中的示例代码用作基础。

我觉得我已经了解了如何构建类和标头的基础知识,但是当尝试在我的类中使用另一个类时,却出现了错误……但仅限于某些功能。

这是我的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);
}

我遇到了错误:

  

没有匹配功能可调用   'esp8266webserver :: ESP8266WebServerTemplate :: on(const char   [2],)'

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

我正在尝试使用许多不同的库来做这种事情,并以此来构建设备,并且我真的很想知道如何使用这种策略有效地清理我的代码,因此了解正确的方法至关重要。 / p>

1 个答案:

答案 0 :(得分:3)

您正在尝试将非静态成员函数传递给server.on("/", handleRoot);,该函数需要签名void()的可调用对象(即,可以不带任何参数调用并返回void的可调用对象)

但是,非静态成员函数不是没有任何参数就不能调用的函数。它至少需要一个参数,即指向类实例的隐式this指针。

如果要让处理程序在调用了handleRoot的当前类实例上调用startRoutes,请使用lambda调用成员并捕获this

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

正如@Peter在问题注释中提到的那样,您也没有正确初始化server成员。取而代之的是创建ESP8266WebServer的本地实例,也称为server,但是它对构造函数是本地的,并在构造函数离开时被销毁。该实例与类成员实例无关,只是它们共享类型和名称。

如果要使用server作为参数来初始化port成员,则可以在构造函数的成员初始值设定项列表中进行此操作:

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