C ++回调函数,在静态函数内调用成员变量

时间:2014-11-03 22:14:57

标签: c++ static callback

我最近决定开始使用回调函数来让我的生活更轻松一些。但是,我有一个问题:

#include <iostream>
#include <functional>
#include <memory>

class setCallback
{
public:
        setCallback() {}
        setCallback(std::function<int()> func) : callback(func) { }

        int call() { return callback(); }
private:
        std::function<int()> callback;
};

class callThis
{
public:
        callThis() : number(10) {}

        static int another()
        {
                return number;
        }
        int number;
};

int main(int argc, char** argv[])
{
        std::shared_ptr<setCallback> caller;
        std::shared_ptr<callThis> funcholder;

        funcholder.reset(new callThis);
        caller.reset(new setCallback(funcholder->another));

        std::cout << caller->call() << "\n";

        std::cin.get();
}

从代码中可以看出,我将函数从“callthis”拉入“setCallBack”。这允许我保留该功能以供以后使用,如果需要的话。但是,如果我尝试将一个成员变量从“callthis”加载到静态函数中,它显然不起作用(使用值),这非常有效。

有解决方法吗?我想使用静态函数访问类中找到的变量;可选地避免在传入回调时使用静态函数(但我认为由于回调的工作方式,这是不可能的。)

我听说过包装类,但我不完全确定如何实现它。一些见解将不胜感激。

非常感谢。

编辑:

解决了具有回调函数的调用变量,由B Sahu

使用回调解决了调用函数,但没有将函数调用为静态并保持合理解耦

我研究了如何使用C ++ 11调用非静态函数;我认为如果有人最终遇到同样的问题可能会有用。这与R Sahu提出的原理相同,然而,使用其中的类型和程序最终会更清洁。使用std :: bind(class :: func,object)可以有效地获得相同的结果。

int main(int argc, char** argv)
{
    std::function<void(void)> somefunc;

    Functionholder func;

    somefunc = std::bind(&Functionholder::say, &func);
}

归功于:This beautiful person

当在一个更复杂的例子中使用时,有一个类来保存要调用的函数,一个调用者类将接受该函数并在需要时调用它和一个binder / state类(注意,我用它来代替游戏UI),你真的可以得到一些合理的整洁和解耦的代码:

#include <iostream>
#include <functional>

class Functionholder
{
public:
    void say() { std::cout << "hello!\n"; }
};

class CallbackHandler
{
public:
    CallbackHandler(){}
    CallbackHandler(std::function<void()> call) { callback = call; }

    void update() 
    { 
        //something happens to call this
        callback();
    }

    std::function<void()> callback;
};

class TheState
{
public:
    TheState()
    {
        hand = CallbackHandler(std::bind(&Functionholder::say, &func));
    }

    void update() { hand.update(); }

    Functionholder func;
    CallbackHandler hand;
};

int main(int argc, char** argv)
{
    TheState state;
    state.update();

    std::function<void(void)> somefunc;

    std::cin.get();
}

如果您有任何改进,请告诉我们!

1 个答案:

答案 0 :(得分:1)

提供使用用户指定的数据调用回调函数的功能。然后,使用回调函数中的数据。

#include <iostream>
#include <functional>
#include <memory>

class setCallback
{
   public:
      setCallback() {}
      setCallback(std::function<int(void*)> func) : callback(func) { }

      int call(void* data) { return callback(data); }
   private:
      std::function<int(void*)> callback;
};

class callThis
{
   public:
      callThis() : number(10) {}

      static int another(void* data)
      {
         callThis* ptr = static_cast<callThis*>(data);
         return ptr->number;
      }
      int number;
};

// Fixed this line. You had
// int main(int argc, char** argv[])
int main(int argc, char** argv)
{
   std::shared_ptr<setCallback> caller;
   std::shared_ptr<callThis> funcholder;

   funcholder.reset(new callThis);
   caller.reset(new setCallback(callThis::another));

   std::cout << caller->call(funcholder.get()) << "\n";

   std::cin.get();
}