这是我的code:
#include <iostream>
#include <stdio.h>
using namespace std;
typedef void (*CallbackType)(double);
class LFO
{
private:
public:
CallbackType target;
inline void Process() {
double value = 1.3;
target(value);
}
};
class ExternalObject
{
private:
public:
double mTest = 1.0;
ExternalObject() {
}
~ExternalObject() {
}
inline void PrintValue(double value) {
cout << "passed: " << value << endl;
}
};
int main ()
{
ExternalObject eo;
LFO lfo;
lfo.target = eo.PrintValue;
lfo.Process();
}
我想在LFO的Process中执行ExternalObject的回调PrintValue。但似乎我不能以这种方式通过lfo.target
?我哪里错了? (对不起,我是C ++的新手;在JavaScript中我就是这样做的。)
答案 0 :(得分:1)
Foo
的定义如下:
CallbackType
这基本上是一个typedef void (*CallbackType)(double);
并且不返回任何内容的函数(double
)。
当你像这样指定void
时:
eo.PrintValue
您的类型不匹配:因为lfo.target = eo.PrintValue;
是PrintValue
类的非静态成员函数。非静态成员函数有一个&#34;隐藏&#34; 附加参数,它是指向类实例的ExternalObject
指针。
有点像this
的实际声明:
PrintValue
您可以修复void ExternalObject::PrintValue(ExternalOject* this, double value)
PrintValue
static方法 ExternalObject
,因为static
方法不具备this
{1}}指针参数。 E.g:
class ExternalObject {
public:
// Note: you don't need "inline" here
static void PrintValue(double value) {
...
}
P.S。通常,当您有回调时,C ++中的常见模式是在回调中提供额外的void*
参数。这可用于为回调函数提供一些上下文,包括传递前面提到的this
指针(因此静态成员函数回调可以使用this
指针来调用非静态方法)。
P.P.S。该回调样式通常可在C接口API中找到。在C ++中,您可能需要考虑std::function
(例如std::function<void(double)>
)。
您也可以考虑使用带有重载operator()
的类作为回调的设计(所谓的&#34;仿函数&#34; ,或&#34;函数对象& #34; ),例如:
#include <functional> // for std::function
#include <iostream>
class LFO {
public:
std::function<void(double)> Target;
void Process() {
double value = 1.3;
Target(value);
}
};
class ValuePrinter {
public:
void operator()(double value) const {
std::cout << "passed: " << value << '\n';
}
};
int main() {
LFO lfo;
lfo.Target = ValuePrinter();
lfo.Process();
}
作为另一种选择,您可以使用 std::bind
和double
参数的占位符,例如在main
内:
ExternalObject eo;
LFO lfo;
using namespace std::placeholders;
lfo.Target = std::bind(&ExternalObject::PrintValue, &eo, _1);
lfo.Process();
可编辑的代码:
#include <functional>
#include <iostream>
class LFO {
public:
std::function<void(double)> Target;
void Process() {
double value = 1.3;
Target(value);
}
};
class ExternalObject {
public:
double mTest = 1.0;
ExternalObject() = default;
void PrintValue(double value) {
std::cout << "passed: " << value << '\n';
}
};
int main() {
ExternalObject eo;
LFO lfo;
using namespace std::placeholders;
lfo.Target = std::bind(&ExternalObject::PrintValue, &eo, _1);
lfo.Process();
}