我在基于文本的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;
}
}
答案 0 :(得分:1)
在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()
发送了一些消息,那么您应该能够找出差异。
答案 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
类的状态,因此编译器可能会执行某些优化,并且如果方法尝试,则阻止成功编译修改状态。