Search code examples
c++windows-console

Class properties not holding values


im working in a text-based RPG game, but when I'm setting the values to X variable, when I access that propertie again, it is in its default value, am I doing something wrong?

class Game
{
private:
    bool podeAndar;
    bool estaBatalhando;
    Jogador _jogador;
    Mapa _mapa;
public:
    Game() { }

    Game(Jogador _j){
        _jogador = Jogador(_j.getNome());
        _mapa.LoadMapa();
        podeAndar = true;
        estaBatalhando = false;
    }

    ~Game(void)
    {
    }

    Jogador getJogador() {
        return _jogador;
    }

    void setJogador(Jogador v) {
        _jogador = v;
    }
}

My "Player" class

#pragma once
#include "Criatura.h"

#include <string>

class Jogador :
    public Criatura
{
private:
    int _cap;
public:

    Jogador(std::string nome)
    {
        setNome(nome);
        setCap(150);
    }

    Jogador() { }

    ~Jogador(void)
    {
    }

    int getCap(){
        return _cap;
    }

    void setCap(int v){
        _cap = v;
    }
}

Them my "Main" - when I set the value, when I'm following it in the debugger, it sets the value correctly, but when I access the game.getJogador().getCap() again, it has the default value 150.

int _tmain(int argc, _TCHAR* argv[])
{
     Jogador _player = Jogador("Kyore");
     Game game = Game(_player);

     while(true){
          std::cout << game.getJogador().getCap(); //print 150
          game.getJogador().setCap(100); //set cap to 100
          std::cout << game.getJogador().getCap(); //print 150 again
          break;
     }
}

Solution

  • In Game class, change this

    Jogador getJogador() {
            return _jogador;
        }
    

    to

    Jogador& getJogador() {
            return _jogador;
        }
    

    And add one more method only to read:

    const Jogador& getJogador()const {
                return _jogador;
            }
    

    Update for the questions asked in the comment

    1. To fix your specific issue of value remaining as 150 inspite of setting a new value, converting the return type to reference is enough.
      Why returning reference works? Because, whenever your original version of getJogador() is called, a copy of the object is created. Even though you are changing its value, you are actually changing the value of the temporary object created, not the original one.
      So as your intention is to modify the original object, we need to access the original one, not its temporary copy. Reference is the better mechanism in such cases (pointer being the other mechanism, but less safer than reference)
    2. Now about why I suggested the new over load of a const member function, returning a const reference: this is to highlight to you that it is possible to still get the object without changing its internal state unintentionally.
      Your sample code does not differentiate between the two getJogador() functions.
      So to understand, add these two functions to your Game class:

      void DontManipulate()const { std::cout<<getJogador().getCap(); }
      void Manipulate() { std::cout<<getJogador().getCap(); }

      See the compiler error(s) that you get: - it should throw light on the differences.
      Additionally, if you std::cout some message in both the getJogador() functions, you should be able to figure out the differences.