Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing and Executing Functions From A Class (C++)

I have a class called "Tasks" that needs to store methods from other classes, and be able to execute them. I'd like it to work like this:

Window *window = new Window();
Tasks* tasks = new Tasks();
tasks.m_tasks.Add(window.Create("My Window"));

Then I could call that window creation from my tasks class, by iterating over the stored tasks and executing each one:

tasks.ExecuteTasks();

What would be the datastructure of "m_tasks" that stores the functions, and how could I call them?

like image 288
user1043761 Avatar asked Feb 07 '26 09:02

user1043761


2 Answers

I would use a std::list<std::function<void()> >, or boost::function if std::function is not available.

And you'll need to change the syntax of that Add call to avoid executing the Create method right away.

C++11:

class Tasks {
public:
    void Add(const std::function<void()>& f)
    { callbacks_.push_back( f ); }

    void Add(std::function<void()>&& f)
    { callbacks_.emplace_back( std::move( f ) ); }
    // ...
private:
    std::list<std::function<void()> > callbacks_;
};

int main() {
    Window window;
    // ...
    tasks.Add( [&]() { window.Create("My Window"); } );
    // ...
}

C++03:

class Tasks {
public:
    void Add(const boost::function<void()>& f)
    { callbacks_.push_back( f ); }

private:
    std::list<boost::function<void()> > callbacks_;
};

int main() {
    // ...
    tasks.Add( boost::bind( &Window::Create, boost::ref(window), "My Window" ) );
    // ...
}
like image 140
aschepler Avatar answered Feb 08 '26 22:02

aschepler


You could use a list of tr1 or boost ::functions as @aschepler says, but this scenario is perfect for boost::signals.

class Tasks {
    boost::signal<void ()> m_tasks;
};

// ...
tasks.m_tasks.connect(&someFunction);

// ExecuteTasks:
tasks.m_tasks();

This allows for a lot of extra functionality, like handling arguments, returns, and letting clients disconnect their tasks if they want to.

like image 44
Todd Gardner Avatar answered Feb 08 '26 22:02

Todd Gardner



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!