Как передать метод класса как аргумент в пользу другой функции в C++ и openGL?

Я знаю эту вещь работы:

void myDisplay()
{
...
}
int main()
{
...
glutDisplayFunc(myDisplay)
...
}

таким образом, я пытался включать myDisplay () функция к классу, который я сделал. Поскольку я хочу перегрузить его в будущем с другим классом. Однако компилятор жалуется это

argument of type 'void (ClassBlah::)()' does not match 'void(*)()' .

Вот, что я пытаюсь сделать:

class ClassBlah
{
   ....
   void myDisplay()
   ....
}
......
int main()
{

    ...
    ClassBlah blah
    glutDisplayFunc(blah.myDisplay)
    ...
}

Кто-либо знает, как решить эту проблему?Большое спасибо.

11
задан 23 March 2010 в 00:27
поделиться

4 ответа

Я сам столкнулся с этой проблемой при написании движка C ++ Glut. Вот как я работал над этим:

Я поместил их в начало моей программы. Cpp / main.cpp

// Function prototypes
void doRendering( void );
void processMouse( int, int ) ;
void processMouseClick(int button, int state, int x, int y);
void keyboardInput(unsigned char c, int x, int y);

Назначьте эти функции для обратных вызовов перенасыщения здесь:

glutDisplayFunc(doRendering);
glutIdleFunc(doRendering);
glutPassiveMotionFunc(processMouse);
glutMotionFunc(processMouse);
glutMouseFunc(processMouseClick);
glutKeyboardFunc(keyboardInput);

Создайте свой собственный класс, который обрабатывает их самостоятельно и затем заставьте содержимое наших статических функций просто вызывать методы экземпляра этого класса. Ваша основная функция должна создать новый экземпляр класса в main (в моем случае ... App * newApp).

void doRendering( void )
{
    newApp->updateScene();
    newApp->drawScene();
}

void processMouse(int x, int y)
{
    newApp->processMouse(x, y);
}

void processMouseClick(int button, int state, int x, int y)
{
    newApp->processMouseClick(button, state, x, y);
}

void keyboardInput(unsigned char c, int x, int y)
{
    newApp->keyboardInput(c, x, y);
}

Надеюсь, что это объясняет.

5
ответ дан 3 December 2019 в 06:46
поделиться

Во-первых, в нестатических функциях-членах есть неявный указатель "this", поэтому вам придется изменить ваш void myDisplay() в ClassBlah на статический. Обходить это ограничение неудобно, поэтому в C++ faq lite сказано не делайте этого

Затем вы должны иметь возможность передавать функции как ClassBlah::myDisplay.

В зависимости от мотивации перегрузки (т.е. вы собираетесь менять реализации местами во время выполнения или только во время компиляции?) вы можете рассмотреть возможность использования статического класса "обработчик", который содержит указатель на ваш базовый класс и делегирует ответственность через него.

9
ответ дан 3 December 2019 в 06:46
поделиться

Вы можете использовать Boost bind для функций-членов, например, создать поток на функцию-член:

class classA
{
public:
    void memberThreadFunc(int i);
};

void main()
{
    classA a;
    boost::thread( boost::bind(&classA::memberFunc, &a, 123) );
}
1
ответ дан 3 December 2019 в 06:46
поделиться

Вы не можете. glutDisplayFunc принимает параметр типа void (*) () , а не void (ClassBlah ::) () . Если вы не хотите и не можете изменить источник перенасыщения, вам не повезло.


Многие API C, использующие обратные вызовы, передают указанный пользователем параметр void * обратному вызову, который можно использовать для хранения указателя на свой класс. Затем вы можете передать бесплатную функцию, которая преобразует данные пользователя в указатель класса, а затем вызывает функцию-член. Однако то, как устроено перенасыщение, этого не позволяет.

0
ответ дан 3 December 2019 в 06:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: