-1

I am new to C++ and would like to know how can a member function of a class be passed to another function which takes a function pointer as a parameter. For the code I tried, I get the error of "reference to non-static member function must be called".

Edit: Making the function static would solve the issue but then I would not be able to access the variables defined in the class.

file.cpp:

#include "fooHdr.h"
class bar {
    void clbck() 
    {
       // Do something 
    }
    void init()
    {
        foo(clbck()); 
    }
};
fooHdr.h:
void foo(void (*hndlr)()); 
fooHdr.c
void foo(void (*hndlr)()) { };
Cherbo
  • 57
  • 1
  • 6
  • The return type of `clbck()` is `void` so you can't use it as a parameter anywhere. You probably meant to write `foo(clbck);`, but that's a class member function, it need's to be declared as `static` class member function to get that working. – πάντα ῥεῖ Jan 27 '21 at 18:29
  • 1
    Also note that (pointers to) member functions are *not* the same a (pointers to) non-member functions. – Some programmer dude Jan 27 '21 at 18:31
  • And all of this should be in any [decent text-book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) or class. – Some programmer dude Jan 27 '21 at 18:38

1 Answers1

1

Member function pointers are different from normal function pointers. A normal function pointer looks like this:

void foo() {}

void (*Func)() = foo;    // Function pointer.

And a member function pointer looks like this:

class MemberTest {
public:
    void foo() {}
};

void (MemberTest::*Func)() = &MemberTest::foo;  // Member function pointer. Notice the '&' operator here.

int main()
{
    MemberTest test;
    (test.*Func)();    // This is how to call member function pointers.
}

Accordingly, for your problem there, you need to define it as a member function pointer and not like a normal function pointer:

void foo(void (bar::*hndlr)()); 

And when calling the foo() function, it must return the address of the member function:

void init()
{
    foo(&bar::clbck); 
}

But still, you can't call the function from foo() like this, as it doesn't have the current instance of the bar object. So we have to make another parameter which takes the pointer to the current object:

void foo(bar* pBar, void (bar::*hndlr)()); 
...
foo(this, &bar::clbck); 

So now, when calling the member function from foo(), you can do it like this:

(pBar->*hndlr)();

Note: Add a forward declaration on top of the function foo() or else the compiler might complain saying that bar is undefined.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
D-RAJ
  • 3,263
  • 2
  • 6
  • 24
  • @RemyLebeau Thank you for correcting me. I edited it. – D-RAJ Jan 27 '21 at 19:15
  • Thank you for your answer, but the foo() function is a given header function that cannot be modified. – Cherbo Jan 27 '21 at 20:22
  • @Cherbo Then your `clbck()` needs to be marked as `static` if you want to pass it to `foo`. And also you cannot do `foo(clbck()); `, you need to do `foo(clbck);`. – D-RAJ Jan 27 '21 at 20:26