2014-10-27 48 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類,所以編譯器可能會執行某些優化,並且如果該方法嘗試修改狀態,則會阻止編譯成功。