Я работаю в текстовой 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;
}
}
Мой класс «Player»
#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;
}
}
Это мой «Main» — когда я устанавливаю значение, когда я слежу за ним в отладчике, он устанавливает значение правильно, но когда я снова получаю доступ к 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;
}
}
В Game
класс, измени это
Jogador getJogador() {
return _jogador;
}
в
Jogador& getJogador() {
return _jogador;
}
И добавьте еще один метод только для чтения:
const Jogador& getJogador()const {
return _jogador;
}
Обновление для вопросов, заданных в комментарии
150
несмотря на установку нового значения, преобразование типа возвращаемого значения в reference
достаточно. getJogador()
называется, копия объектаReference
являетсяpointer
будучи другим механизмом, но менее безопасным, чем reference
)Теперь о том, почему я предложил новую перегрузку const member
функция, возвращающая const reference
Это означает, что вы все равно можете получить объект без непреднамеренного изменения его внутреннего состояния.
Ваш пример кода не различает два getJogador()
функции.
Чтобы понять, добавьте эти две функции к вашему Game class
:
void DontManipulate()const { std::cout<<getJogador().getCap(); }
void Manipulate() { std::cout<<getJogador().getCap(); }
Смотрите ошибки компилятора, которые вы получите: — это должно пролить свет на различия.
Кроме того, если вы std::cout
какое-то сообщение в обоих getJogador()
функции, вы должны быть в состоянии выяснить различия.
Проблема в вашем getJogador()
метод.
В C ++ объекты могут передаваться «по значению» — именно здесь программа (обычно) копирует необработанные данные объекта в новое место, тогда как в C # и Java объекты всегда передаются по ссылке (не считая C #). struct
s, которые передаются по значению аналогично C ++). C ++ будет использовать «конструктор копирования» для выполнения этой копии. C ++ создаст конструктор копирования, если он явно не определен в вашем коде, подпись имеет вид ClassName(ClassName& other);
конструктор копирования по умолчанию (неявный) выполняет поверхностную операцию, основанную на членах.
В вашем случае ваш getJogador
метод возвращает копию вашего Jogador
данные поля экземпляра.
Измените метод, чтобы он возвращал ссылку или указатель, например так:
Jogador& getJogador() const {
return _jogador;
}
или же
Jogador* getJogador() const {
return &_jogador;
}
const
Модификатор сообщает компилятору, что этот метод не предназначен для изменения состояния вашего Game
класс, поэтому компилятор может выполнять определенные оптимизации, а также предотвращать успешную компиляцию, если метод пытается изменить состояние.