类属性不保持值

时间:2014-10-27 04:15:28

标签: c++ windows-console

我在基于文本的RPG游戏中工作,但是当我将值设置为X变量时,当我再次访问该属性时,它是默认值,我做错了吗?

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;
    }
}

我的"播放器"类

#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;
    }
}

他们我的&#34;主要&#34; - 当我设置值时,当我在调试器中跟随它时,它会正确设置值,但是当我再次访问game.getJogador()。getCap()时,它的默认值为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;
     }
}

2 个答案:

答案 0 :(得分:1)

Game课程中,更改此

Jogador getJogador() {
        return _jogador;
    }

Jogador& getJogador() {
        return _jogador;
    }

再添加一个方法来阅读:

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

更新评论中提出的问题

  1. 要将您的特定问题值保留为150,尽管设置了新值,但将返回类型转换为reference就足够了。
    为什么返回参考作品?  因为,每当调用getJogador()的原始版本时,该对象的副本就是 创建。即使你正在改变它的价值,你实际上也是 更改创建的临时对象的值,而不是原始值 一。
    因此,您的目的是修改原始对象,我们需要 访问原始的,而不是临时副本。 Reference是 在这种情况下更好的机制(pointer是另一种机制,但不如reference更安全)
  2. 现在我为什么建议const member的新过载 函数,返回const reference:这是为了向您强调,仍然可以在不意外更改其内部状态的情况下获取对象。
    您的示例代码不区分两个getJogador()函数。
    要理解,请将这两个功能添加到Game class

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

    查看你得到的编译器错误: - 它应该对差异有所了解  此外,如果您在std::cout函数中getJogador()发送了一些消息,那么您应该能够找出差异。

答案 1 :(得分:1)

问题在于您的getJogador()方法。

在C ++中,对象可以“按值”传递 - 这是程序(通常)将对象的原始数据复制到新位置的位置,而在C#和Java对象中总是通过引用传递(不计算C#的{{ 1}}传递的值类似于C ++)。 C ++将使用“复制构造函数”来执行此复制。如果代码中没有显式定义,C ++将创建复制构造函数,签名的格式为struct,默认(非显式)复制构造函数执行浅层的成员复制操作。

在您的情况下,您的ClassName(ClassName& other);方法会返回getJogador实例字段数据的副本。

更改方法以返回引用或指针,如下所示:

Jogador

Jogador& getJogador() const {
    return _jogador;
}

Jogador* getJogador() const { return &_jogador; } 修饰符通知编译器此方法不是要修改const类的状态,因此编译器可能会执行某些优化,并且如果方法尝试,则阻止成功编译修改状态。