Re: passing member function pointers to a function
Thanks for the suggestions everyone. I guess what I had in mind was
something along the lines of:
class ode_solver{
...
double (*f) (double,double);
void solve();
...
};
ode_solver s;
s.f = & arbitraryclass.arbitraryfunction;
s.solve();
This would work perfectly fine if f pointed to a non-member function
-- and this idea is used a lot in C.
I will be needing to use the ode_solver with an extremely general set
of functions f that might come from all different kinds of classes.
It is not an option to guarantee that f is a member of a particular
class or has a particular name (i.e. f or operator(double,double)). I
would much prefer if I didn't have to modify the code of
arbitraryclass, if that's possible.
So, there is no way to do something like this in C++ with member
functions?
I could make "every" class in my library derive from
class its_a_class{
// empty
};
class my_class : public its_a_class{
double f1(double x, double t);
double f2(double x, double t);
....
// lots of data/functions that f1 and f2 need to know about/call
....
};
class ode_solver : public its_a_class{
double (its_a_class:: *f)(double, double);
....
};
my_class foo;
ode_solver s;
....
s.f = & foo.f1;
s.solve;
....
s.f = &foo.f2;
s.solve;
etc.
Would this work? But, it's ridiculous, right? There's not a better
way?
It seems like the suggestions are along the lines of that f should be
itself a class. So...
class ode_solver{
TwoArgFunc f;
};
but then...
class my_class{
TwoArgFunc f1;
....
};
s.f = foo.f1;
is no good, because f1 needs to know about the data of my_class and to
call other functions in my_class to evaluate itself (like a member
function does).
Thanks again.
On Feb 23, 5:04 pm, Mark P <use...@fall2005REMOVE.fastmailCAPS.fm>
wrote:
tbring...@gmail.com wrote:
I am a c++ newbie, so please excuse the ignorance of this question.
I am interested in a way of having a class call a general member
function of another class.
Specifically, I am trying to write an ordinary differential equation
class that would solve a general equation in the form:
dx/dt = f(x,t).
The ode class shouldn't know anything about f, except how to call it.
My first thought was to have a data member that stores a pointer to
the function f like:
double (*f) (double, double);
However, I learned that f could not point to a non-static member
function of a different class. This is bad for me, because I need to
use the solver for functions that are complicated to evaluate and
depend on many parameters. A simple example:
class my_f{ public:
double a;
double f(double x, double t){ return t+x*a;}
};
my_f foo; foo.a = 7;
I would like the ode solver to call foo.f(x,t). I could make
double (my_f::* f)(double, double);
a member of the ode solver, but then I would have to write a new ode
solver for every new class of functions to be used for f or to have
all these derive from some kind of base class, which I would prefer to
avoid.
My question is: is there a simple and elegant way to do this? I would
think that similar issues have been encountered many times before.
Thanks.
How are you passing the function object to the solver in the first
place? Or perhaps this is really the root of your question? The two
most direct approaches would be to use either inheritance or templates.
In the former, you would have some abstract base class like:
class TwoArgFcn
{
public:
virtual double evaluate( double x, double t) = 0;
};
Then a derived class defines evaluate() as appropriate and your solver
takes an object of type TwoArgFcn& or something similar.
If you use templates, then you solver is templated on the type of the
function object:
template <typename FcnClass>
class Solver
{
public:
Solver( FcnClass& input_fcn) : input_fcn( input_fcn) {}
private:
void solve() { /* use input_fcn.f() */ }
FcnClass& input_fcn;
};
Here you assume that the template class FcnClass defines some function f
(which will be verified when the template is instatiated).
-Mark