446,238 Members | 1,771 Online Need help? Post your question and get tips & solutions from a community of 446,238 IT Pros & Developers. It's quick & easy.

# passing member function pointers to a function

 P: n/a 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. Feb 23 '07 #1
18 Replies

 P: n/a tb*******@gmail.com 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 // 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

 P: n/a Please note that my C++ is so rusty it squeaks when I walk. On Feb 23, 10:36 pm, tbring...@gmail.com 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 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 Feb 23 '07 #3

 P: n/a tb*******@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 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 Feb 23 '07 #4

 P: n/a 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 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 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 Feb 23 '07 #5

 P: n/a 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 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 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 Feb 23 '07 #6

 P: n/a > 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 :) Feb 23 '07 #7

 P: n/a tb*******@gmail.com 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 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/ Feb 23 '07 #8

 P: n/a 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

 P: n/a 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

 P: n/a On Fri, 23 Feb 2007 12:36:07 -0800, tbringley 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 about something like this? #include class Aclass { double a,b; public: Aclass(double a_, double b_) : a(a_), b(b_) { } double func1(double x, double t) { return a*x+b*t; } double func2(double x, double t) { return a*x*x+b*t; } }; template

 P: n/a On Sat, 24 Feb 2007 00:04:12 +0000, Lionel B wrote: On Fri, 23 Feb 2007 12:36:07 -0800, tbringley 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 memberfunction of another class.Specifically, I am trying to write an ordinary differential equationclass 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 tothe function f like:double (*f) (double, double);However, I learned that f could not point to a non-static memberfunction of a different class. This is bad for me, because I need touse the solver for functions that are complicated to evaluate anddepend 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 makedouble (my_f::* f)(double, double);a member of the ode solver, but then I would have to write a new odesolver for every new class of functions to be used for f or to haveall these derive from some kind of base class, which I would prefer toavoid.My question is: is there a simple and elegant way to do this? I wouldthink that similar issues have been encountered many times before.Thanks. How about something like this? [snip] Sorry, you wanted your solver to be a class... try something along these lines: #include class Aclass { double a,b; public: Aclass(double a_, double b_) : a(a_), b(b_) { } double func1(double x, double t) { return a*x+b*t; } double func2(double x, double t) { return a*x*x+b*t; } }; class Solver { double c,d; public: Solver(double c_, double d_) : c(c_), d(d_) { } template

 P: n/a Thanks Lionel! That's brilliant. On Feb 23, 7:14 pm, Lionel B class Aclass { double a,b; public: Aclass(double a_, double b_) : a(a_), b(b_) { } double func1(double x, double t) { return a*x+b*t; } double func2(double x, double t) { return a*x*x+b*t; } }; class Solver { double c,d; public: Solver(double c_, double d_) : c(c_), d(d_) { } template

 P: n/a Thanks Lionel! That's brilliant. On Feb 23, 7:14 pm, Lionel B class Aclass { double a,b; public: Aclass(double a_, double b_) : a(a_), b(b_) { } double func1(double x, double t) { return a*x+b*t; } double func2(double x, double t) { return a*x*x+b*t; } }; class Solver { double c,d; public: Solver(double c_, double d_) : c(c_), d(d_) { } template 