グルチャ

C++11でstd::functionとstd::bindとtemplate functionでCallbackを呼び出す

C++11ではstd::functionとstd::bindとtemplate functionを駆使するとCallbackを呼び出せる。
内部のクラス間のやりとりなら、interfaceを使うよりお手軽。

#include <functional>
#include <iostream>

class ClassA
{
public:
    typedef std::function<void(int a, int b)> Func;

    template<typename T>
    static Func BindFunc(void (T::*func)(int a, int b), T *owner)
    {
        return std::bind(func, owner, std::placeholders::_1, std::placeholders::_2);
    }
 
    void SetFunc(const Func &func)
    {
        m_func = func;
    }
 
    void CallFunc(int a, int b) const
    {
        m_func(a, b);
    } 
private:
    Func m_func;
};
 
class ClassB
{
public:
    ClassB(ClassA &classA)
    {
        classA.SetFunc(ClassA::BindFunc(&ClassB::DoFunc, this));
    }

    void DoFunc(int a, int b)
    {
        std::cout << "ClassB a:" << a << ", b:" << b << "\n";
    }
};
 
class ClassC
{
public:
    ClassC(ClassA &classA)
    {
        classA.SetFunc(ClassA::BindFunc(&ClassC::DoFunc, this));
    }

    void DoFunc(int a, int b)
    {
        std::cout << "ClassC a:" << a << ", b:" << b << "\n";
    }
};
 
int main(int argc, char** argv)
{
    ClassA classA;
 
    ClassB classB(classA);
    classA.CallFunc(1, 2);  //ClassB a:1, b:2
 
    ClassC classC(classA);
    classA.CallFunc(3, 4);  //ClassC a:3, b:4
    return 0;
}

Leave a reply

Your email address will not be published.

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Time limit is exhausted. Please reload CAPTCHA.