Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function Pointer (Within Class)

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

like image 362
WoodMath Avatar asked Sep 16 '26 23:09

WoodMath


1 Answers

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.

like image 128
Praetorian Avatar answered Sep 19 '26 13:09

Praetorian



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!