Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing member function pointer to member object in c++

Tags:

I have a problem with using a pointer to function in C++. Here is my example:

#include <iostream>  using namespace std;  class bar { public:     void (*funcP)(); };  class foo { public:     bar myBar;     void hello(){cout << "hello" << endl;}; };  void byebye() {     cout << "bye" << endl; }   int main() {     foo testFoo;      testFoo.myBar.funcP = &byebye;         //OK     testFoo.myBar.funcP = &testFoo.hello;  //ERROR     return 0; } 

Compilator returns an error at testFoo.myBar.funcP = &testFoo.hello;:

ISO C++ forbids taking the address of a bound member function to form a pointer to member function. Say '&foo::hello'

cannot convert 'void (foo::)()' to 'void ()()' in assignment

So i tried it like this:

class bar { public:     void (*foo::funcP)(); }; 

But now the compilator adds one more:

'foo' has not been declared

Is there a way make it work?

Thanks in advance for suggestions

like image 338
Moomin Avatar asked Mar 03 '10 20:03

Moomin


People also ask

How can we call member functions through a pointer to an object?

The pointer to member operators . * and ->* are used to bind a pointer to a member of a specific class object. Because the precedence of () (function call operator) is higher than . * and ->* , you must use parentheses to call the function pointed to by ptf .

Can we call member function using this pointer in constructor?

the constructor is the first function which get called. and we can access the this pointer via constructor for the first time. if we are able to get the this pointer before constructor call (may be via malloc which will not call constructor at all), we can call member function even before constructor call.

Which pointer is not passed to member function?

The 'this' pointer is passed as a hidden argument to all nonstatic member function calls and is available as a local variable within the body of all nonstatic functions. 'this' pointer is not available in static member functions as static member functions can be called without any object (with class name).

Can we pass pointer to function in C?

C programming allows passing a pointer to a function. To do so, simply declare the function parameter as a pointer type.


1 Answers

Taking everyone's suggestions together, your final solution will look like:

#include <iostream>  using std::cout; usind std::endl;  class foo; // tell the compiler there's a foo out there.  class bar  {  public:      // If you want to store a pointer to each type of function you'll     // need two different pointers here:     void (*freeFunctionPointer)();     void (foo::*memberFunctionPointer)(); };   class foo  {  public:      bar myBar;      void hello(){ cout << "hello" << endl; } };   void byebye()  {      cout << "bye" << endl;  }    int main()  {      foo testFoo;       testFoo.myBar.freeFunctionPointer = &byebye;     testFoo.myBar.memberFunctionPointer = &foo::hello;      ((testFoo).*(testFoo.myBar.memberFunctionPointer))(); // calls foo::hello()     testFoo.myBar.freeFunctionPointer();   // calls byebye()     return 0;  }  

The C++ FAQ Lite has some guidance on how to simplify the syntax.

Taking Chris' idea and running with it, you could get yourself something like this:

#include <iostream> using std::cout; using std::endl;  class foo; typedef void (*FreeFn)(); typedef void (foo::*MemberFn)();  class bar { public:   bar() : freeFn(NULL), memberFn(NULL) {}   void operator()(foo* other)   {     if (freeFn != NULL) { freeFn(); }     else if (memberFn != NULL) { ((other)->*(memberFn))(); }     else { cout << "No function attached!" << endl; }   }    void setFreeFn(FreeFn value) { freeFn = value; memberFn = NULL; }   void setMemberFn(MemberFn value) { memberFn = value; freeFn = NULL; } private:   FreeFn freeFn;   MemberFn memberFn; };  class foo { public:   bar myBar;   void hello() { cout << "foo::hello()" << endl; }   void operator()() { myBar(this); } };  void bye() { cout << "bye()" << endl; }  int main() {   foo testFoo;    testFoo();    testFoo.myBar.setMemberFn(&foo::hello);   testFoo();    testFoo.myBar.setFreeFn(&bye);   testFoo();    return 0; } 
like image 128
Bill Avatar answered Oct 26 '22 06:10

Bill