Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > passing member function pointers to a function

Reply
Thread Tools

passing member function pointers to a function

 
 
tbringley@gmail.com
Guest
Posts: n/a
 
      02-23-2007
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.

 
Reply With Quote
 
 
 
 
Piyo
Guest
Posts: n/a
 
      02-23-2007
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:

>
> 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.
>

This can help give you an idea how to approach this problem.

-----------------------------------------------

// Use boost/function and functors
#include <boost/function.hpp>

// create a functor
class my_f
{
public:
my_f( double a ) : m_a(a) {}
double operator()(double x, double t){ return t+x*m_a;}
private:
double m_a;
};

// this is another functor
class my_y
{
public:
my_y( double a ) : m_a(a) {}
double operator()(double x, double t) { return t+x*m_a;}
private:
double m_a;
};

class ODE
{
public:
void solve( boost::function<double (double, double)> f)
{
// call f here
double result = f( 1.0, 1.0 );
}
};

int
main()
{
ODE solver;
solver.solve( my_f(20.0) );
solver.solve( my_y(100.0) );
}
 
Reply With Quote
 
 
 
 
roy axenov
Guest
Posts: n/a
 
      02-23-2007
Please note that my C++ is so rusty it squeaks when I walk.

On Feb 23, 10:36 pm, (E-Mail Removed) wrote:
> 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).


I believe you're making a conceptual mistake here. In the
design you're describing f(x,t) is not represented by a
method of a class, but by the class itself, and f a (x,t) -
by an instance of the class representing f(x,t) functions.
That's why you probably shouldn't try passing a pointer to
a method, pass a reference to the object instead. If you
have more general questions about all of this, you probably
should follow-up to comp.object.

> The ode class shouldn't know anything about f, except how
> to call it.


That's pretty much a textbook description of an interface.

[...]

> 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.


That kinda defeats the purpose of OOD, doesn't it?

> 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.


I'm not sure if this will work for you, but consider this
bare-bones implementation:

#include <iostream>

class interface_function
{
public :
virtual double operator ( )
( double x , double t ) const = 0 ;
} ;

class ode
{
public :
static void solve ( const interface_function & f ) ;
} ;

void ode :: solve ( const interface_function & f )
{
std :: cout <<
f
(
static_cast < double > ( 1 ) ,
static_cast < double > ( 1 )
) ;
std :: cout << std :: endl ;
}

class f : public interface_function
{
public :
double a_ ;
f ( ) : a_ ( 1 ) { }
virtual double operator ( )
( double x , double t ) const ;
} ;

double f :: operator ( )
( double x , double t ) const
{
return t + x * a_ ;
}

class g : public interface_function
{
public :
double a_ ;
g ( ) : a_ ( 1 ) { }
virtual double operator ( )
( double x , double t ) const ;
} ;

double g :: operator ( )
( double x , double t ) const
{
return t - x * a_ ;
}

int main ( )
{
f f1 ;
g g1 ;
ode :: solve ( f1 ) ;
ode :: solve ( g1 ) ;
f1 . a_ = 5 ;
g1 . a_ = 5 ;
ode :: solve ( f1 ) ;
ode :: solve ( g1 ) ;
}

--
roy axenov

 
Reply With Quote
 
Mark P
Guest
Posts: n/a
 
      02-23-2007
(E-Mail Removed) 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
 
Reply With Quote
 
tbringley@gmail.com
Guest
Posts: n/a
 
      02-23-2007
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 <(E-Mail Removed)>
wrote:
> (E-Mail Removed) 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



 
Reply With Quote
 
tbringley@gmail.com
Guest
Posts: n/a
 
      02-23-2007
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 <(E-Mail Removed)>
wrote:
> (E-Mail Removed) 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



 
Reply With Quote
 
Piyo
Guest
Posts: n/a
 
      02-23-2007
>
> 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?
>

Hi, instead of us trying to determine your program requirements and
write example code that will fit it properly, I think it is better to
just teach you about calling a pointer to a member function because it
is possible to do so.

Here is a guide to doing that:

http://www.parashift.com/c++-faq-lit...o-members.html

Good Luck with that
 
Reply With Quote
 
Grizlyk
Guest
Posts: n/a
 
      02-23-2007

(E-Mail Removed) wrote:
>
> My first thought was to have a data member that stores a pointer to
> the function f like:
> double (*f) (double, double);
>
> 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


Pointer is no needed here, use ordinary member

template<class T>
class
{
T obj;

public:
double f(double x, double t){ return obj.f(x, t);}
};

The main OO design rule is: "find all that can be changed and encapsulate
it". Incapsulator is function or class. You have said, that you will change
implementation of concrete function - see design pattern "strategy".

At design stage to find design patterns without external help do not speak
implementations details (as "pointer") language, do not take the details as
predefined invariants, describe what you want in design terms: interface,
message and implementation, method.

--
Maksim A. Polyanin
http://grizlyk1.narod.ru/cpp_new

"In thi world of fairy tales rolls are liked olso"
/Gnume/


 
Reply With Quote
 
tbringley@gmail.com
Guest
Posts: n/a
 
      02-23-2007

I am aware that it is possible to have a pointer to a member
function. However, such a pointer must know the name of the class
that contains the member function to which it points. This is what I
am trying to circumvent.

Please do not write example code for me if you don't want to. I just
included sample code and details of my project to give make more
concrete what I am trying to do. In the simplest terms, I would just
like to know if there is a way for class A to call a member function
of class B without class A knowing that the function it is calling is
a member of class B.

Thanks.




On Feb 23, 6:32 pm, Piyo <(E-Mail Removed)> wrote:
> > 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?

>
> Hi, instead of us trying to determine your program requirements and
> write example code that will fit it properly, I think it is better to
> just teach you about calling a pointer to a member function because it
> is possible to do so.
>
> Here is a guide to doing that:
>
> http://www.parashift.com/c++-faq-lit...o-members.html
>
> Good Luck with that



 
Reply With Quote
 
tbringley@gmail.com
Guest
Posts: n/a
 
      02-23-2007

I am aware that it is possible to have a pointer to a member
function. However, such a pointer must know the name of the class
that contains the member function to which it points. This is what I
am trying to circumvent.

Please do not write example code for me if you don't want to. I just
included sample code and details of my project to give make more
concrete what I am trying to do. In the simplest terms, I would just
like to know if there is a way for class A to call a member function
of class B without class A knowing that the function it is calling is
a member of class B.

Thanks.




On Feb 23, 6:32 pm, Piyo <(E-Mail Removed)> wrote:
> > 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?

>
> Hi, instead of us trying to determine your program requirements and
> write example code that will fit it properly, I think it is better to
> just teach you about calling a pointer to a member function because it
> is possible to do so.
>
> Here is a guide to doing that:
>
> http://www.parashift.com/c++-faq-lit...o-members.html
>
> Good Luck with that



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Member function pointers to member functions with default arguments Hamish C++ 3 01-25-2008 06:46 AM
Passing a member function as a parameter of a member function Azdo C++ 2 03-06-2007 11:21 AM
Smart pointers and member function pointers n2xssvv g02gfr12930 C++ 3 11-27-2005 10:51 AM
Passing pointer to member function to different member function that then calls for_each pookiebearbottom@yahoo.com C++ 8 05-24-2005 01:50 PM
Passing a pointer to member function as a parameter to another member function Newsgroup - Ann C++ 5 07-30-2003 02:54 AM



Advertisments