I wanted to pass a function object to a class, and the class will use the function object to do some job inside the class.
But the problem is that, I don't what the function object will be passed in. So I figured that, define a void *
pointer in the class, this pointer will be initialized with the function object which will be passed in.
Code goes below:
class A
{
public:
//...
void doSomeJob(int x)
{
(*functor)(x); //use the function object to process data x
}
private:
//...
void *functor; //function object's pointer will be assigned to this pointer
};
But the code doesn't work. I guess, can't use void *functor
that way.
I know I can use template class
to finish the job, but my question is, can I still do the job using pointer to function object
and how?
PS
To make my problem clearer, there may be several function objects which differ from each other by how they process data, I don't what function object will be passed in, but I do know each of them will take a int
parameter.
Just as some answers tell, I can do the job through function pointer
, but function object has more utilities than function pointers, such as states
, and that's what I'm gonna use.
You can't call a function object of a type unknown to you at the call site if its type is not stored somewhere accessible to the call machinery.
There are two options:
If you can use C++11 or boost, you can use
std::function
resp.boost::function
:Here the type is stored (in an implicit form) inside the mechanism of the
function
template.Otherwise, if you can require that all function objects passed have a class type derived from a specific base class, you can create an abstract base class:
Here the type is stored in the virtual table of the function object.
If you really can't use boost, you also might write a similar solution yourself. The key word is "type erasure", and it basically works by generating on the fly a derived object from a known base class (as in my second solution) which knows about your object's type and can call it. It might be done roughly as follows (untested code):