c++ - 通过引用传递对象函数
问题描述
我试图通过引用传递一个对象函数。我只能用一个简单的功能让它工作。
代码:
class Light {
...... omitted some code here, not relevant .......
void toggle2() {
Serial.println("TOGGLE");
};
}
class Button {
public:
OneButton pin;
void single();
Button(int _pin, void (&_single)() ){
pin = OneButton(_pin, false, false);
_single();
pin.attachClick(_single);
}
};
Light lights[] = {
Light("Cozinha", CONTROLLINO_A15, CONTROLLINO_R0)
};
Button buttons[] = {
Button(CONTROLLINO_A0, lights[0].toggle2)
};
上面的代码给出了按钮声明错误
no instance of constructor "Button::Button" matches the argument list -- argument types are: (int, void ())
toggle2
function 是一个 void 函数,但程序可能因为 Light 类型而令人困惑?
如果我用一个简单的函数编写代码,它会很好地工作,如下所示:
void toggle() {
Serial.println("TOGGLE");
};
Button buttons[] = {
Button(CONTROLLINO_A0, toggle)
};
有什么建议吗??
解决方案
我已经消除了代码示例中的所有干扰,专注于传递和调用函数指针的方法。
class Light {
public:
void toggle2() {
};
};
class Button {
public:
Button(int _pin,
void (Light::*single)(), // the function. Compiler needs to know the class
// the function belongs to or it'll assume a free
// function
Light& light) // class instance to invoke the member function on
{
(light.*single)(); // note the weird-looking invocation syntax.
// all of it is essential and easily <expletive deleted>ed up.
// C++FAQ recommends using a macro to keep from leaving
// anything out. They don't recommend macros lightly.
// note you will want to store these two variables as Button
// class members rather than using them immediately.
// I did the call in the constructor to keep the example simple.
}
};
Light lights[] = {
Light()
};
Button buttons[] = {
Button(1, // the pin
&Light::toggle2, // address of the fully-qualified member function
lights[0]) // instance to invoke member function on
};
可以在指向成员函数的指针中找到血淋淋的细节和一些非常好的建议
请注意,由于Button
现在必须携带Light
对其使用的实例的引用,因此在范围足够广的函数中创建lights
和Buttons
局部变量变量是一个有吸引力的选择。
std::function
为了完整起见,下面是Lambda 表达式的样子。
#include <functional>
class Light {
public:
void toggle2() {
};
};
class Button {
public:
Button(int _pin,
std::function<void()> single){ // std::function contains the necessary
// instance reference
single(); // no muss, no fuss function call
}
};
Light lights[] = {
Light()
};
Button buttons[] = {
Button(1,
[](){lights[0].toggle2();}) // lambda expression wrapping the function call
};
推荐阅读
- java - 如何使用 jasper 报告在 java bean 中生成具有 3 个嵌套列表的表?
- batch-file - 通过批处理脚本从 .CSV 中删除行
- javascript - 如何定位 dropEffect 光标以进行样式设置
- spring-boot - Spring Boot 2.1.4 版应用程序在启动后很快终止
- sql - 在 sql 空间数据中使用变量
- ibm-cloud - IBM Watson Assistant:通过 IBM Cloud Functions 检索特定对话
- r - 面板数据框中分组观察的条件
- c# - 外键不包含完整主键时如何先做多对多代码
- ruby-on-rails - 工人在被杀时不断重启
- javascript - 从 JavaScript 中的 iframe 获取跨度