2014-10-27 74 views
0

即时通讯工作在基于文本的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; 
    } 
} 

他们我的“主” - 当我设置的值,当我跟随它在调试器,它正确地设定值,但是当我访问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; 
    } 
} 

回答

1

Game类,改变这个

Jogador getJogador() { 
     return _jogador; 
    } 

Jogador& getJogador() { 
     return _jogador; 
    } 

并添加一个方法只阅读:

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

更新在评论

  1. 提出的问题要解决您的具体问题值仍然为150,尽管设置了新的值,转换r eturn类型为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(); }

    见你让编译器错误(S): - 它应该在的差异扔光。
    此外,如果您std::cout函数getJogador()中的某些消息,您应该能够找出差异。

+0

谢谢,它工作完美。为了学习的目的,没有const方法它不会工作?为什么?当我使用.getJogador()时,我们会调用其中一个?返回地址或常量的那个?再次感谢。 – Kyore 2014-10-27 14:46:31

+1

对不起,我无法立即回复您的评论。现在编辑答案 - 检查它是否提供了一些更多信息,以便您可以弄清楚自己。 – elimad 2014-10-30 05:20:22

1

问题出在您的getJogador()方法中。在C++中,对象可以“按值”传递 - 这是程序(通常)将对象的原始数据复制到新位置的地方,而在C#和Java对象中总是通过引用传递(不包括C#的struct这是通过类似于C++的值传递的)。 C++将使用“复制构造函数”来执行此副本。如果C++没有在你的代码中明确定义,C++将创建拷贝构造函数,签名的形式为ClassName(ClassName& other);,默认(非显式)拷贝构造函数执行浅层的成员拷贝操作。

对于您的情况,您的getJogador方法正在返回您的Jogador实例字段数据的副本。

更改该方法返回引用或指针,像这样:

Jogador& getJogador() const { 
    return _jogador; 
} 

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

const改性剂通知,该方法不意欲修改的状态的编译器你的Game类,所以编译器可能会执行某些优化,并且如果该方法尝试修改状态,则会阻止编译成功。