I'm trying to use a function pointer (fnPtr) to reference a class method (fnEmpty) from within another class method, (in this case the constructor).
The setup program main.cpp is
#include <iostream>
#include "test.hpp"
int main(int argc, char* argv[]){
Test test;
return 0;
}
and a test.hpp that reads
#ifndef _test_h
#define _test_h
#include <iostream>
class Test {
private:
public:
void (*ptrEmpty)(void);
void fnEmpty(){ std::cout << "Got Here" << std::endl;};
Test(){ ptrEmpty = fnEmpty; };
~Test(){};
};
#endif
Most of the material on the net details being able to reference a class method from outside the class (see microsoft page and newty.de), but not from inside the class (as I have done).
Using the above files gives the error
In file included from main.cpp:6: ./test.hpp:11:21: error: reference to non-static member function must be called;
So 1) why does this error result?
If I change fnPtr declaration on line 10 to be a static so it reads
static void fnEmpty(){ std::cout << "Got Here" << std::endl;};
This seems to solve the problem. But that begs the question 2) Why does it accept a 'static' if the error says only a 'non-static' is allowed?
If I remove the static and instead change line 11 (by adding the &) so it reads
Test(){ ptrEmpty = &fnEmpty; };
I get a whole new error that reads
./test.hpp:11:21: error: must explicitly qualify name of member function when taking its address
Unfortunately replacing with
Test(){ Test::ptrEmpty = Test::&fnEmpty; };
Or variations not including the Test:: prefix as was done in the links given above do not solve the problem.
I was under the impression that as far as function pointers go, when referencing a function (say fn),
ptr = fn;
is equivalent to
ptr = &fn;
3) So why am I getting two different sets of errors when I include and exclude the '&'
So the ultimate question I have is::
4) What is the correct way to point to a class method (from within a different method of the same class)? Do I need to include the 'Classname::' qualifier when Its within the same class?
Thanks, Jeff
fnEmpty is a non-static member function, which means it takes an implicit first argument, a pointer to the Test instance it's being invoked on (the this pointer). So the type of a pointer to that member function is
void (Test::*ptrEmpty)();
Next, to form a pointer to a member function, you need to use the syntax &ClassName::MemFnName So, within your constructor
ptrEmpty = &Test::fnEmpty;
Now your example should compile. You can invoke the function that ptrEmpty points to by using
Test t;
(t.*(t.ptrEmpty))();
When you change fnEmpty to be static it no longer receives the implicit this pointer argument, so it's just like any other pointer to function, and your code compiles.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With