Trouble with pointer to member function

Ok so I am working on a game and I'm in the process of developing my Player class. Anyways, what I have is a keyboard function that is called in my main function to make a shape move.
1
2
3
4
5
6
7
8
9
10
11
12
13
void myKeyboardFunction(unsigned char key, int x, int y)
{
   switch ( key )
   {
     case 'd':
        pointX += 0.2;
        break;    
     case 'a':
        pointX -= 0.2;
        break;
...blah blah blah more controls......
   }
}

to call the function I have this in my main function and it works perfectly.
 
glutKeyboardFunc(myKeyboardFunc);


What I want to do is move myKeyboardFunc into my Player class, and this is what I have so far.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Player
{
private:
	GLfloat pointX;
	GLfloat pointY;
public:

	void playerControls(unsigned char key, int x, int y);

} Player1, Player2, Player3, Player4;

void Player::playerControls( unsigned char key, int x, int y)
{ 
	switch ( key ) 
	{
		case 'd':
			pointX +=0.2;
			break;
	....more keys.......
        }
}

But when I try to call it, trying to copy my previous method,
 
glutKeyboardFunc(Player1.playerControls);

I get an error
 
error C3867: 'Player::playerControls': function call missing argument list; use '&Player::playerControls' to create a pointer to member

I've tried messing around with this suggestion but then I get an error saying it can't convert parameters. I would just like to understand why the arguments become a problem when I make the function a member of my class, when the first method I used is so easy. Of course help on how to fix this would be nice.

I know it's probably simple as I'm sort of stepping outside of my boundaries with classes and functions in this project, but I figure I have to learn somehow.
Last edited on
closed account (S6k9GNh0)
http://www.newty.de/fpt/index.html
The thing is that member functions have an implicit parameter (this pointer) that is passed to the functions. So, essentially, your member function has the following signature: void playerControls(Player* this, unsigned char key, int x, int y). So to pass it in form of callback to glutKeyboardFunc, you need to wrap it so that the this pointer would be saved and passed to the member function. However, this is not so easy :)

An exemplary implementation might be like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <boost/function.hpp>
#include <boost/bind/bind.hpp>
#include <vector>

typedef int (*TCallback)(int x);

int user(TCallback f, int x)
{
    return 2 * f(x);

}

int f1(int x)
{
    return x + 1;
}

class T {
public:
    int member(int x) { return x + 2; }
};

class Dispatcher {
public:
    typedef boost::function<int (int)> TCallable; 

    static void addListener(TCallable callable) { listeners.push_back(callable); }

    static int call(int f) 
    {
        int x = 0;
        for (int i = 0; i < listeners.size(); ++i) {
            x += listeners[i](f);
        }
        return x;
    }

private:
    static std::vector<TCallable> listeners;
};

std::vector<Dispatcher::TCallable> Dispatcher::listeners;

void main()
{
    T t;
    user(f1, 3);
    Dispatcher::addListener(f1);
    Dispatcher::addListener(boost::bind(&T::member, boost::ref(t), _1));

    user(&Dispatcher::call, 2);

}


Of course, you will need to adapt the function type to glutKeyboardFunc requirements, but this should give you the general idea. If you're confused with all the boost stuff - refer to its documentation - it's a good exercise anyway.

If you have questions - just ask :)
Topic archived. No new replies allowed.