How to get class's function pointer for non-st

2019-08-28 21:54发布

问题:

I need to pass class function as argument for glutIdleFunc. This construction doesn't work:

void (*func)(void) = this->step();
glutIdleFunc(func);

and this too:

void (*func)(void) = Core::step();
glutIdleFunc(func);

How can I do it? Sorry for my stupidity... :)

回答1:

In C++, callbacks such as the one accepted by glutIdleFunc() have to be static methods. Try:

class Core
{
public:
    static void step()
    {
        // ...
    }
};

glutIdleFunc(Core::step);


回答2:

glutIdleFunc simply does not support calling a non-static member function. If you want the idle loop to call a method of an object, you will need to place a pointer to the object in a global variable, and have a regular function or static member that calls your step method on that global object.

There are two ways you could get this done. The simpler way:

// global scope
Core *foo = NULL;
void myIdleCallback()
{
    foo->step();
}

// when initializing, in main or whatever
{
    // ...
    foo = &theThingIWantToCall;
    glutIdleFunc(&myIdleCallback);
    // ...
}

Or, for a slightly greater encapsulation:

// work these into your Core declaration
class Core {
    static class Core* foo;
    static void myIdleCallback() {
        foo->step();
    }
};

// at global scope
Core *Core::foo = NULL;

// at initialization time
{
    // ...
    Core::foo = &theThingIWantToCall;
    // or if foo is private, add a static method to set it and call that
    glutIdleFunc(&Core::myIdleCallback);
    // ...
}


回答3:

Member function of a class have a hidden parameter called this, which is a pointer to their calling object. So when you try to use it a callback, function signatures won't match, you should use static functions which do not have the hidden this parameter.



回答4:

I think the problem is this line: void (*func)(void) = Core::step();

See you describe the function's signature as void (*func)(void), this is the signature of a C function, not a c++ method. All non-static member methods in c++ are similar to c functions but in addition have a hidden parameter which is a pointer to 'this'.

Try changing the signature to void (Core::*func)(void) = Core::step();

You can call from an instance of the object using: Core test; (test.*test.func)();

"f.test" returns the pointer to the method, and the ".*" operator calls the pointer-to-member function on a class