C++奇怪的函数指针行为

C++ Weird function pointer behaviour

本文关键字:指针 函数 C++      更新时间:2023-10-16

这是一个简单的opengl/sdl程序。通常有一个巨大的deque,其中程序保存显示数据,例如三角形将入/读入/从取消队列中读取,就像这样(GL_Begin....顶点 1 ....顶点 2 ...顶点 3 ...GL_End )

项结构

enum Shapes{
    LINE,
    POLYGON,
    TRIANGLE
};
struct Item{
    int id;
    int type;
    Shapes shape;
    double x;
    double y;
    double z;
};

void GEngine::CC2D(int id,double x,double y){ // Change Coordinates ... Move the Item
    for(int i=0;i<Items.size();i++){
        Item* item = &Items[i];                  // Pointer to the item INSIDE the deque because we need to edit it, we can not create a new instance of Item
        if(item->id == id && item->type == 2){
            item->x += x;
            item->y += y;
        }
    }
    DrawScene();
}
void GEngine::PollEvents( void (*Event)() ){
    int mbpressed = 0; // Mouse button pressed flag
    int mouse_xpre = 0;
    int mouse_ypre = 0;
    int move_id = 0; // TESTING
    while(1){
        while( SDL_PollEvent( &event ) ){
            switch( event.type ){
                case SDL_MOUSEMOTION:{
                    if(mbpressed == 1){
                        mouse_x = event.motion.x; // X2
                        mouse_y = event.motion.y; // Y2
                    //  (*Event)();
                    //  CC2D(  (   X2  -   X1     ),(   Y2  -   Y1     )
                        CC2D(move_id,(mouse_x-mouse_xpre),(mouse_y-mouse_ypre));      // The difference between the current and the previous mouse position is equal to the DX and DY which will be used to move the vertices.
                        mouse_xpre = mouse_x;     // X1
                        mouse_ypre = mouse_y;     // Y1
                        SDL_Delay(20);
                    }
                    break;

现在问题来了。如果我使用 CC2D(move_id,(mouse_x-mouse_xpre),(mouse_y-mouse_ypre));它工作正常,但是如果我将 CC2D 函数添加到事件中,算法会失败,而不是用鼠标移动项目,而是远离屏幕。

换句话说。

case SDL_MOUSEMOTION:{
                        if(mbpressed == 1){
                            mouse_x = event.motion.x; // X2
                            mouse_y = event.motion.y; // Y2
                        //  (*Event)();
                        //  CC2D(  (   X2  -   X1     ),(   Y2  -   Y1     )
                        CC2D(move_id,(mouse_x-mouse_xpre),(mouse_y-mouse_ypre));      // The difference between the current and the previous mouse position is equal to the DX and DY which will be used to move the vertices.
                        mouse_xpre = mouse_x;     // X1
                        mouse_ypre = mouse_y;     // Y1
                        SDL_Delay(20);
                    }
                    break;
}

^ 工作正常。

GEngine gEngine;
void Event(){
            gEngine.CC2D(0,(gEngine.mouse_x-gEngine.mouse_xpre),(gEngine.mouse_y-gEngine.mouse_ypre));
    }
int main(int argc, char *argv[]){
... code ...
gEngine.PollEvents(&Event);
return 0; // NEVER REACHED
}

case SDL_MOUSEMOTION:{
                    if(mbpressed == 1){
                        mouse_x = event.motion.x; // X2
                        mouse_y = event.motion.y; // Y2
                        (*Event)();
                        mouse_xpre = mouse_x;     // X1
                        mouse_ypre = mouse_y;     // Y1
                        SDL_Delay(20);
                    }
                    break;
}

不。。。

为了进一步简化事情:

Case SDL_MOUSEMOTION: ...... code ..... CC2D( params) ........

工作正常,但

Event(){ CC2D( params ) } // Main.cpp
Case SDL_MOUSEMOTION: ...... code ..... (*Event)() ........ // GEngine.cpp

无法按预期工作

您在PollEvents中声明局部变量:

int mouse_xpre = 0;
int mouse_ypre = 0;

请注意,它们被命名为 mouse_xpremouse_ypre 。然后在你正在做的回调中

gEngine.CC2D(0,(gEngine.mouse_x-gEngine.mouse_xpre),(gEngine.mouse_y-gEngine.mouse_ypre));
//                                      ^^^^^^^^^^                           ^^^^^^^^^^

访问成员变量。您需要删除局部变量的声明,以便它们不会隐藏成员变量,并且您将在两个位置使用成员变量。