我正在制作一个简单的基于文本的胭脂游戏。在我的代码中,我为“房间”创建了一个类,我在主文件中创建了一个名为“Dungeon”的房间实例。该对象范围产生了问题。我在'initGame()'函数中创建了它,但后来我无法在主游戏循环中访问它。
我将发布所有相关代码,谢谢!
room.h
#include <string>
#include "ConsoleCommands.h"
using std::string;
class room
{
public:
room(void);
room(string name);
~room(void);
//This creates the cells and populates the map//
static const int cellsX = 15;
static const int cellsY = 10;
string NAME;
int map;
void writeMap();
};
的main.cpp
int main(void)
{
initGame();
cout << "WELCOME, " + Player.NAME + " ";
return 0;
};
void initGame(void)
{
initCells();
lifeForm Player(100, 100, 100, newGameMenu());
room Dungeon("Dungeon");
}
答案 0 :(得分:2)
当initGame返回时,Dungeon和Player会被破坏。从函数中返回房间和/或播放器实例。
您可以使用游戏结构:
struct Game
{
Game() : Player(100, 100, 100, newGameMenu()), Dungeon("Dungeon")
{
}
lifeForm Player;
room Dungeon;
}
然后
int main(void)
{
Game g;
cout << "WELCOME, " + g.Player.NAME + " ";
return 0;
};
答案 1 :(得分:0)
正如您所说,问题在于范围。对象
lifeForm Player(100, 100, 100, newGameMenu());
room Dungeon("Dungeon");
仅存在于
范围内void initGame(void)
要解决这个问题,你可以尝试一些事情
1)在main中初始化对象。只需将声明从initGame()移到main即可。这不是非常模块化的,您希望在名为init的函数中使用初始化代码。
2)在init函数中创建初始化代码,并将对象返回到main。让initRoom()和initLifeForm()像以前一样创建,然后分别返回类型为room和lifeForm的对象。然后在主要副本中通过初始化程序或使用=。
int main(void)
{
room theRoom = initRoom();
lifeForm theLifeForm = initLifeForm();
}
这并不比1)好多了,甚至可能更糟,但至少你已经删除了初始化函数的特定初始化。当然,在这种情况下,为什么没有为此目的使用特殊的无参数初始化构造函数?
3)有一个游戏对象。这可能就是你想要的。这里room和lifeForm成为Game的成员,而initGame是Game构造函数。
答案 2 :(得分:0)
您的initGame函数会创建一些本地对象
void initGame(void)
{
initCells();
lifeForm Player(100, 100, 100, newGameMenu());
room Dungeon("Dungeon");
}
让我们快速浏览一下这些陈述:
room Dungeon("Dungeon");
这是一个变量声明,但C ++使用作用域,这意味着上下文很重要。这里的范围是一个函数,所以你正在做的是声明一个“房间”的实例,被称为“Dungeon”,并通过调用room::room(std::string)
来构建。
在C ++中,本地对象在堆栈中声明 - 这意味着当您离开作用域时程序展开堆栈,这些对象将被强制消失。
所以,如果你是C-ify上面的陈述,这大致是你会产生的代码:
void initGame(void)
{
initCells();
lifeForm* Player = alloca(sizeof(Player));
Player->lifeForm(100, 100, 100, newGameMenu());
room* Dungeon = alloca(sizeof(Dungeon));
std::string dungeonName = std::string("Dungeon");
Dungeon->room(dungeonName);
// scope ends
// destruct Dungeon
Dungeon->~room();
// destruct Player
player->~lifeForm();
// the stack space is automatically "released" by
// leaving the function
}
这里的结果是物体完全消失了。如果你希望它们持久存在,你需要通过返回它们,在main中声明它们并通过引用它们来传递它们,或者将它们封装在它们自己的对象中来管理它们的生命周期。
答案 3 :(得分:-1)
如果您经常使用这些变量,可以将它们创建为任何函数之外的全局变量:
lifeForm g_Player;
room g_Dungeon;
int main(void)
{
initGame();
cout << "WELCOME, " + Player.NAME + " ";
return 0;
};
void initGame(void)
{
initCells();
g_Player = Player(100, 100, 100, newGameMenu());
g_Dungeon = Dungeon("Dungeon");
}
然后,只要您在初始游戏后需要访问这些对象,就可以使用全局对象
void Death(void)
{
g_Player.Lives--;
}