简体   繁体   中英

Can i pass a function from a class to a constructor of another class and store it there to call later? C++

So basically I'm making buttons in a game, and the buttons are a called Button. The class i want the function from to store is called SoccerLevelsClass. I've tried looking into function pointers, but I'm not sure what's going on though i think it's the correct thing to do.

I want to save the function of SoccerLevelsClass as a member of Button. Would i do something like this?

//MenuButton.h

#ifndef MenuButton
#define MenuButton
....

class Button
{
public:
       Button(void(*SoccerLevelsClass::func)());
       void (*SoccerLevelsClass::function)();
       ....

}
#endif


//MenuButton.cpp
#include <MenuButton.h>
Button::Button(void(*SoccerLevelsClass::func)())
{
   function=func;     //something like this
}

I know the code is probably way off, but I'd like to know if anybody has any suggestions. All i really want to know is if it's possible.

Yes, this can be done - either with function pointers like in your example, or with lambdas if you can use C++11.

However, since you want to call a bound function of another class, you would need to pass/store pointer to an instance of that class as well to do that, unless the function is static.

In C++11, this is trivial:

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

void apply() {
    _f();
}

Bar(void (Foo::* f)()) { 
    _f = std::bind(f, Foo());
}

In C++03, this is a little tricky. Note in both versions I construct a temporary to call the member function, but I'm not sure whether it is necessary to store an instance of the class.

#include <iostream>
#include <functional>

struct Foo
{
    Foo() { }
    void stuff() { 
        std::cout << "hi\n";
    }
};

struct Bar
{
    void (Foo::* _f)();

    void apply() {
        (Foo().*_f)();
    }

    Bar(void (Foo::* f)()) { 
        _f = f;
    }
};

int main()
{
    Bar bar(&Foo::stuff);
    bar.apply();
}

For what you are trying to do I would use the observer pattern:

class IFootballObserver
{
public:
    virtual void OnBallKicked() = 0;
    virtual ~IFootballObserver() {}
};

class Fooball
{
public:
     Fooball(IFootballObserver& obs)
      : mObs(obs)
    {
      // Call the observer interface at any time like so:
      mObs.OnBallKicked();
    }
private:
    IFootballObserver& mObs;
};

class Button : public IFootballObserver
{
public:
  // Football could be passed in/owned by something else
  Button() : mFootball(*this) { }

  void DoSomething()
  {
     // Called when foot ball is kicked
  }
private:
  virtual void OnBallKicked()
  {
      DoSomething();
  }

Fooball mFootball;
};

I find this easier than using function pointers/std::function. Plus you could have a vector of observers and notify many objects of events.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM