我有一个 Arduino 项目。每只动物都有胃。它想告诉动物,我应该饿了。所以我要使用一个回调,这是我从其他语言中知道的。当我想在动物中使用回调来传递虚拟方法(然后被覆盖)时,我遇到了无效类型问题。
动物.h
#ifndef animal_h
#define animal_h
#include <Arduino.h>
#include <stomach.h>
class Animal
{
public:
Animal();
protected:
virtual void getHungry(uint8_t hunger) =0;
private:
Stomach _stomach;
};
#endif
动物.cpp
#include "animal.h"
Animal::Animal()
{
_stomach.setCallback(getHungry);
/*
here is the issue:
argument of type "void (Animal::*)(uint8_t hunger)" is incompatible with parameter
of type "void (*)(uint8_t)"
*/
}
胃.h
#ifndef stomach_h
#define stomach_h
#include <Arduino.h>
class Stomach
{
public:
void setCallback(void (*)(uint8_t));
private:
void (*_callbackHunger)(uint8_t amount) = nullptr;
};
#endif
胃.cpp
#include "stomach.h"
void Stomach::setCallback(void (*callback)(uint8_t amount))
{
_callbackHunger = callback;
}
我也尝试过使用模板,但未能将正确的(模板)类传递给 setCallback 函数。
问题出在动物构造函数中。 _stomach.setCallback(gethungry) 在我的 IDE 中显示错误:
“void (Animal::)(uint8_t饥饿)”类型的参数与“void ()(uint8_t)”类型的参数不兼容
您确实应该编辑您的问题并将其减少为一段,也许两段。
错误告诉您预期的回调只是一个普通函数,但提供的回调是一个成员方法。
C++ 中的方法有一个隐藏参数,即
this
指针。因此,您不能只在需要函数的地方传递方法,因为调用者没有 this
指针可提供给方法调用。
您可以通过多种方式解决此问题:
static
,并让它接受void* userData
参数。使注册函数不仅接受回调,还接受用户数据指针。当调用注册的回调时,还要向其传递注册的用户数据指针。然后,回调将用户数据指针转换为注册者的实例,并调用注册者的方法,如下所示: static void myStaticCallBack( void* userData )
{
((MyClass*)userData)->myMemberCallback();
}