使用类成员的 C++ 回调

标签 c++ function callback member

我知道这个问题已经被问过很多次了,因此很难深入挖掘并找到一个简单的有效示例。

我知道了,它很简单,适用于 MyClass...

#include <iostream>
using std::cout;
using std::endl;

class MyClass
{
    public:
        MyClass();
        static void Callback(MyClass* instance, int x);
    private:
        int private_x;
};

class EventHandler
{
    public:
        void addHandler(MyClass* owner)
        {
            cout << "Handler added..." << endl;
            //Let's pretend an event just occured
            owner->Callback(owner,1);
        }
};

EventHandler* handler;

MyClass::MyClass()
{
    private_x = 5;
    handler->addHandler(this);
}

void MyClass::Callback(MyClass* instance, int x)
{
    cout << x + instance->private_x << endl;
}

int main(int argc, char** argv)
{
    handler = new EventHandler();
    MyClass* myClass = new MyClass();
}

class YourClass
{
    public:
        YourClass();
        static void Callback(YourClass* instance, int x);
};

如何重写,使 EventHandler::addHandler()MyClassYourClass 一起工作。抱歉,这只是我大脑的工作方式,在我理解为什么/如何工作之前,我需要先看一个简单的例子来说明什么是有效的。如果您有最喜欢的方法来完成这项工作,现在是展示它的时候了,请标记该代码并将其发回。

[编辑]

有人回答了,但在我打勾之前答案被删除了。 在我的案例中,答案是模板化函数。将 addHandler 更改为此...

class EventHandler
{
    public:
        template<typename T>
        void addHandler(T* owner)
        {
            cout << "Handler added..." << endl;
            //Let's pretend an event just occured
            owner->Callback(owner,1);
        }
};

最佳答案

您可以使用新 C++11 标准中的功能,而不是使用静态方法并传递指向类实例的指针:std::functionstd::bind :

#include <functional>
class EventHandler
{
    public:
        void addHandler(std::function<void(int)> callback)
        {
            cout << "Handler added..." << endl;
            // Let's pretend an event just occured
            callback(1);
        }
};

addHandler 方法现在接受一个 std::function 参数,这个“函数对象”没有返回值并接受一个整数作为参数。

要将其绑定(bind)到特定函数,您可以使用 std::bind:

class MyClass
{
    public:
        MyClass();

        // Note: No longer marked `static`, and only takes the actual argument
        void Callback(int x);
    private:
        int private_x;
};

MyClass::MyClass()
{
    using namespace std::placeholders; // for `_1`

    private_x = 5;
    handler->addHandler(std::bind(&MyClass::Callback, this, _1));
}

void MyClass::Callback(int x)
{
    // No longer needs an explicit `instance` argument,
    // as `this` is set up properly
    cout << x + private_x << endl;
}

添加处理程序时需要使用 std::bind,因为您明确需要指定隐含的 this 指针作为参数。如果你有一个独立的功能,你不必使用 std::bind:

void freeStandingCallback(int x)
{
    // ...
}

int main()
{
    // ...
    handler->addHandler(freeStandingCallback);
}

让事件处理程序使用 std::function 对象,也可以使用新的 C++11 lambda functions :

handler->addHandler([](int x) { std::cout << "x is " << x << '\n'; });

关于使用类成员的 C++ 回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54381300/

相关文章:

php - 在 PHP 中是否可以在变量中使用函数

function - 拥有长初始化方法是不好的做法吗?

c++ - C++ 中模板化别名的 Typedef

c++ - 该标准是否定义了共同基础?

c++ - 程序计算错误,类型转换

javascript - 回调函数示例

Javascript FOR 循环回调

c++ - Sprite 纹理不从图像中划分碎片 C++

java - 用于 C++ 实现的 native JNI 静态方法的 Java 运行时错误

javascript - Node.js Array.map() 是异步的吗?