使用类成员的C ++回调 [英] C++ callback using class member

查看:118
本文介绍了使用类成员的C ++回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这个问题已经问了很多遍了,因此很难深入研究这个问题,并找到一个简单的例子来说明什么是有效的.

I know this has been asked so many times, and because of that it's difficult to dig through the cruft and find a simple example of what works.

我已经知道了,它很简单,并且适用于MyClass ...

I've got this, it's simple and it works for 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一起使用.抱歉,这只是我的大脑运作的方式,我需要先了解一个简单的运作方式示例,然后才能理解其运作方式.如果您有一种最喜欢的方法来进行这项工作,现在是时候炫耀一下,请标记该代码并将其发布回去.

How can that be rewritten so EventHandler::addHandler() will work with both MyClass and YourClass. I'm sorry but it's just the way my brain works, I need to see a simple example of what works before I can comprehend why/how it works. If you've got a favorite way to make this work now's the time to show it off, please markup that code and post it back.

已回答,但答案被删除,我无法打勾. 在我的情况下,答案是模板函数.将addHandler更改为此...

It was answered but the answer was deleted before I could give the checkmark. The answer in my case was a templated function. Changed addHandler to this...

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标准中的功能,而不必使用静态方法并传递指向类实例的指针, http://en.cppreference.com/w/cpp/utility/functional/function> std::function

Instead of having static methods and passing around a pointer to the class instance, you could use functionality in the new C++11 standard: std::function and std::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参数,并且此函数对象"没有返回值,并使用整数作为参数.

The addHandler method now accepts a std::function argument, and this "function object" have no return value and takes an integer as argument.

要将其绑定到特定功能,请使用std::bind:

To bind it to a specific function, you use 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:

You need to use std::bind when adding the handler, as you explicitly needs to specify the otherwise implicit this pointer as an argument. If you have a free-standing function, you don't have to use std::bind:

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

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

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

Having the event handler use std::function objects, also makes it possible to use the new C++11 lambda functions:

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

这篇关于使用类成员的C ++回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆