Is it possible to save a function (pointer?) To an object?

I was looking for this, but I think I'm just confused.

What I'm trying to do is save a function pointer in an object and is called later in another thread.

What I represent is a constructor that will use a pointer to a function and the parameters that will be passed to this function pointer. This object will also have a run () method that will run the specified function pointer and a wait_until_completed () method, which blocks until the function is started.

A function pointer should be a function of another object, if that makes sense. for instance

Foo::*Bar(int); 

I have wait_until_completed () working using pthread_cond_t, but I am stuck in a function pointer function in this function and feel like I'm just running in circles.

Any tips?

EDIT: This is for school (any general understanding of mine), so third-party libraries don't work: /

It seemed to me that I did a very poor job explaining this in order to give me a sample code (with the exception of all synchronization materials)

 class Foo { public: Foo(void (Bar::*function) (int), int function_param) { // Save the function pointer into this object this->function = &function; // Save the paramater to be passed to the function pointer in this object param = function_param; } run() { (*function)(param); } private: // The function pointer void (Bar::*function) (int) = NULL; // The paramater to pass the function pointer int param; } 

This is briefly what I am trying to do. However, I’m not sure if this is the syntax or I’m stupid, but I can’t figure out how to actually do this and force it to compile.

Thoughts? And thanks for all the advice so far :)

+4
source share
6 answers

First, you would like typedef use your function type, which simplifies its reuse and reduces the chance of errors.

 typedef void (Bar::*function_type)(int); 

Now you can use typedef as follows:

 Foo(function_type func, int func_param) : function_(func) , param_(func_param) { } 

It is also recommended that you use the initialization list to initialize member variables (you can find more about initialization lists here ).
However, you still cannot call the function. Class member functions, also called related functions, MUST be used with an instance of an object because they are associated with them. Your run function should look like this (you also forgot the return type):

 void run(Bar* object){ (object->*function_(param_)); } 

It uses the special operator ->* to call member functions using a member function pointer.
In addition, you cannot initialize most variables directly inside the class (only constant constant constants, such as static const int i = 5; ). Now you can create an instance of the Foo object and call the launch function on it.
Here you get a fully compiled example:

 #include <iostream> using namespace std; class Bar{ public: void MyBarFunction(int i){ cout << i << endl; } }; class Foo { public: typedef void (Bar::*function_type)(int); Foo(Bar* object, function_type function, int function_param) : object_(object) // save the object on which to call the function later on , function_(function) // save the function pointer , param_(function_param) // save the parameter passed at the function { } void Run() { (object_->*function_)(param_); } private: // The object to call the function on Bar* object_; // The function pointer function_type function_; // The paramater to pass the function pointer int param_; }; int main(void){ // create a Bar object Bar bar; // create a Foo object, passing the Bar object // and the Bar::myBarFunction as a parameter Foo foo(&bar, &Bar::MyBarFunction, 5); // call Bar::MyBarFunction on the previously passed Bar object 'bar' foo.Run(); cin.get(); return 0; } 

It might be a little digestible right away, but I hope this helps you understand member function pointers and how to use them. :)

+8
source

Yes, you can save a pointer to a function:

 struct simple_callable_object { void (*f_)(); simple_callable_object(void (*f)()) : f_(f) { } void operator()() { f_(); } }; 

This pattern is generalized to the shell of polymorphic functions, function and the bind binding argument, which can be found in Boost, C ++ TR1, and C ++ 0x.

The function launch scheme is asynchronous, and then the possibility of blocking and waiting for its completion is called the “future”. The C ++ 0x threading support library has std::future and std::async that make this task easier. For instance:

 // pretend 'f' is a long-running task that you want to run asynchronously: int f(int x) { return x * 2; } void g() { std::future<int> fi = std::async(f, 21); // do other meaningful work int x = fi.get(); // blocks until the async task completes } 

You do not need to use std::async to get std::future ; you can write a thread pool or some other object that asynchronously completes tasks and one of them generates and returns futures.

+4
source

It looks like you are trying to reinvent the "command" template. Loki (among many others) should give a reasonable start (although you may have to add thread synchronization yourself).

+3
source

Use the boost function object.

EDIT: here is a trivial example:

 #include <iostream> #include <boost/function.hpp> struct X { int foo(int a, int b) { return a * b; } }; int main(void) { boost::function<int (X*, int, int)> func; func = &X::foo; X x; std::cout << func(&x, 1, 2) <<std::endl; return 0; } 
+2
source

Everything about your sample code is technically correct and should work, except for your attempt to assign NULL to the member variable where it was declared. This can only be done using static integrals, and function pointers are not taken into account.

So delete this line and your example should work just fine, what can I say.

With that said, you should prefer initializers for assignment in the constructor body. Ergo should look like this:

 Foo(void (Bar::*fun) (int), int fparam) : function(fun), param(fparam) {} 

Edit: Oooh, I missed something in your OP. You already accept a pointer to a member function as your parameter, but try to call it a normal function. The form of using void (*)(int) as your type, rather than void (Bar::*)(int) fixed.

+1
source

And if you don’t take Jerry’s advice, I would suggest using Functors instead of messing with exact function pointers.

http://en.wikipedia.org/wiki/Function_object

However, I recommend Jerry's answer.

0
source

Source: https://habr.com/ru/post/1338157/


All Articles