C++ - Class 私有变量没有改变

C++ - Class private variables not changing

我使用 C++ 编程已有一段时间,并且正在使用 SDL2 库制作游戏。不幸的是,播放器的 class 变量仅在方法中更改,然后不更新以备后用。

Header:

class playerChar {
public:
     void move();
     void handleInput(SDL_Event& lEvent);
     void render();
     int getValX();
     int getValY();
     playerChar();
private:
     int pPosX, pPosY;             //Pos and Direction arent changing
     int pDirectionX, pDirectionY;
     //Posion and Direction (direction. Has value -1, 0 or 1)
     static const int pVel = 10;
     static const int pHeight = 10, pWidth = 10;
     eTexture playerTex;
};

cpp 文件:

playerChar::playerChar(){
     pPosX = 0;
     pPosY = 0;
     pDirectionX = 0;
     pDirectionY = 0;
     playerTex.loadFile("playerIMG.png");
}

void playerChar::handleInput(SDL_Event& lEvent){
     //Key Pressed
     if(lEvent.type == SDL_KEYDOWN && lEvent.key.repeat == 0){
          switch(lEvent.key.keysym.sym){
               case SDLK_UP:
               pDirectionY = -1;
               break;
               case SDLK_s:
               pDirectionY = 1;
               printf("%i\n", pDirectionY);
               break;
               case SDLK_d:
               pDirectionX = 1;
               break;
               case SDLK_a:
               pDirectionX = -1;
               break;
               default:
               break;
          }
     }
     //Key Released
     else if(lEvent.type == SDL_KEYUP && lEvent.key.repeat == 0){
          switch(lEvent.key.keysym.sym){
               case SDLK_w:
               pDirectionY = 0;
               break;
               case SDLK_s:
               pDirectionY = 0;
               break;
               case SDLK_d:
               pDirectionX = 0;
               break;
               case SDLK_a:
               pDirectionX = 0;
               break;
               default:
               break;
          }
     }
}

void playerChar::move(){
     //printf("pos:%i, vel:%i, dir:%i\n", pPosY, pVel, pDirectionY);
     pPosX += pVel*pDirectionX;
     pPosY += pVel*pDirectionY;
     //If Direction is + then it adds velocity
     //If Direction is - then it subtracts
     //If Direction is 0 then adds nothing
     //printf("%i, %i\n", pDirectionX, pDirectionY);
}

void playerChar::render(){
     playerTex.render(pPosX, pPosY);
}

int playerChar::getValX(){
     return pDirectionX;
}

int playerChar::getValY(){
     return pDirectionY;
}

我每帧都用 printf() 检查它们的值(它只是 main() 中使用 getValX/Y() 方法的 printf())。 handleInput() 内部的那个显示它在方法中发生了变化,但是每帧运行的那个说它仍然是 0。我主要测试了按 s.

我试过使 handleInput() 方法 return 成为值,然后创建一个 set 方法,但没有解决问题。

我看了很多网站和论坛,还有一位有经验的朋友也被难住了,无法解决问题。任何帮助是极大的赞赏。

编辑:
对不起,如果我太含糊,我会尽量保持简洁。上面的 cpp 仅包含 playerChar class.
的方法 Main()中的实际实现是

int main(int argc, char* args[]) {
//irrevelvant to question

playerChar player;
while(!quit) {
          fpsTimer.start();
          quit = eInputCheck(event, player);

          if(fpsTimer.getTicks() < ticksPerFrame) {
               SDL_Delay(ticksPerFrame - fpsTimer.getTicks());
          }
          SDL_RenderClear(gRenderer);

          //Render new frame here
          player.move();
          player.render();
          printf("%ix, %iy\n", player.getValX(), player.getValY());
          SDL_RenderPresent(gRenderer);
     }
     eClose();
     return 0;
}  

其中 eInputCheck() 来自 controls.cpp

bool eInputCheck(SDL_Event event, playerChar player){
     while(SDL_PollEvent(&event) != 0){
          player.handleInput(event);
          if(event.type == SDL_QUIT){
               return true;
          }
     return false;
}

我正在努力做到 pDirectionX/Y 将方向更改为 1 / -1 并使 0 停止。问题是,即使按住按钮,当我在 main.

中调用 getValX/Y 方法时,它似乎也没有改变

终端显示为这样,而 运行 我按 s:

0x, 0y
0x, 0y
0x, 0y
0x, 0y
0x, 0y
0x, 0y
0x, 0y
1        //The printf() from inside the handleInput() method
0x, 0y
0x, 0y
0x, 0y
0x, 0y

它甚至在按住按钮的同时给出了这个。 (我按ESC结束程序)

你传一个COPY给eInputCheck,这个copy是在进入函数的时候构造的。您按值传递 playerChar

是这样的

playerChar otherOne = player; // Copies the player to the variable otherOne using a "copy constructor"

C++的案例非常多,是一门非常丰富的语言

playerChar otherOne = player;   // Copies the player (said before).

playerChar &reference = player; // Reference is now refers to otherOne,
                                // a change on reference is reflected
                                // on player.

otherOne = player;              // otherOne was initialized before,
                                // so copy constructor is not called
                                // But a copy assignment is called instead

reference = otherOne;           // Reference was set before to refer to
                                // player, so, a "copy assignment" is
                                // called. Because references always
                                // refers to the same object
                                // initialized with. So, C++ solves this
                                // by copying the otherOne to the object
                                // refered by reference, using a copy 
                                // assignment operator

这是 C++ 中最令人困惑和最困难的部分之一。

你有两个解决方案,

  1. 现代解决方案(我认为这在性能上对 C++ 不利),不变性,尝试 return 来自 eInputCheck 的新播放器实例。

  2. 第二种解决方案是将引用传递给 eInputCheck

请像这样重新定义 eInputCheck:

bool eInputCheck(SDL_Event &event, playerChar &player){
    while(SDL_PollEvent(&event) != 0){
        player.handleInput(event);
        if(event.type == SDL_QUIT){
            return true;
        }
    return false;
}

这会将引用传递给您的函数。 请阅读此内容:

Reference concept in C++

Passing arguments by reference

Copy constructor

Copy assignment