C++ 什么';这回电话怎么了?
这是我的:C++ 什么';这回电话怎么了?,c++,function,callback,C++,Function,Callback,这是我的: #包括 #包括 使用名称空间std; typedef void(*回调类型)(双精度); 类LFO { 私人: 公众: 回调型目标; 内联void进程(){ 双值=1.3; 目标(价值); } }; 类外部对象 { 私人: 公众: 双mTest=1.0; 外部对象(){ } ~ExternalObject(){ } 内联无效打印值(双值){ cout回调类型的定义如下: 这基本上是一个函数,它接受一个double,但不返回任何内容(void) 当您这样分配eo.PrintValue时
#包括
#包括
使用名称空间std;
typedef void(*回调类型)(双精度);
类LFO
{
私人:
公众:
回调型目标;
内联void进程(){
双值=1.3;
目标(价值);
}
};
类外部对象
{
私人:
公众:
双mTest=1.0;
外部对象(){
}
~ExternalObject(){
}
内联无效打印值(双值){
cout回调类型的定义如下:
这基本上是一个函数,它接受一个double
,但不返回任何内容(void
)
当您这样分配eo.PrintValue
时:
类型不匹配:这是因为PrintValue
是ExternalObject
类的非静态成员函数。非静态成员函数有一个“hidden”附加的参数,即指向类实例的this
指针
这有点像PrintValue
的实际声明:
void ExternalObject::PrintValue(ExternalOject* this, double value)
您可以修复使PrintValue
成为ExternalObject
的静态
方法,因为静态
方法没有额外的此
指针参数。例如:
class ExternalObject {
public:
// Note: you don't need "inline" here
static void PrintValue(double value) {
...
}
<强> P.S.通常在回调时,C++中的一个常见模式是在回调中提供附加的<代码>空隙*/Cux>参数。这可以用来给回调函数提供一些上下文,包括传递前面提到的<代码>这个< /C>指针。(因此静态成员函数回调可以使用
this
指针调用非静态方法)
<强> P.P.S.通常在C接口API中发现回调风格。C++中,您可能需要考虑(例如:代码> STD::函数< /C> >)。
您还可以考虑一个具有重载<代码>操作程序()/<代码>的类作为回调(所谓的“函子”或“函数对象”),例如:
可编译代码:
#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();
}
#包括
#包括
类LFO{
公众:
功能目标;
无效过程(){
双值=1.3;
目标(价值);
}
};
类外部对象{
公众:
双mTest=1.0;
ExternalObject()=默认值;
无效打印值(双值){
std::cout它们的类型不同,一个是自由函数,另一个是成员函数您应该向PrintValue
方法中添加static
。使用static似乎有效!但我不想将该方法设置为静态…正确的类型是void(ExternalObject::*)(double)
,但这会引入对类的依赖关系。您应该使用标准库的函数
类型。因此,您需要声明方法指针,而不是函数指针:typedef void(ExternalObject::*CallbackType)(double);
我不想将方法设置为静态!如果我使用函数Target;
,则需要将回调设置为静态。如果我使用bind,则会引发分段错误:否。我的上一个示例代码可以与std::function和非静态方法一起工作。哦,是的!我在目标和目标上出错,抱歉!为什么使用bind工作:lfo.Target=bind(&ExternalObject::PrintValue,&eo,_1)
但是如果我使用普通函数lfo.Target=eo.PrintValue;
它不会?因为使用bind
我绑定了这个指针(&eo
),所以非静态障碍消失了。这就像我定义了另一个函数,从非静态方法开始,只有一个double
参数。这是一个多么“把戏”啊。所以事实上,你正在“包装”我的ExternalObject::PrintValue函数到一个函数中,第一个参数是this(&eo),第二个参数是value(占位符)我会通过的,对吗?
void ExternalObject::PrintValue(ExternalOject* this, double value)
class ExternalObject {
public:
// Note: you don't need "inline" here
static void PrintValue(double value) {
...
}
#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();
}
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();
}