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();
}