【发布时间】:2016-08-28 03:06:27
【问题描述】:
我在尝试让我的堆栈容器适配器通过引用从 getter 返回时遇到了一些麻烦。每次我尝试对它做一个吸气剂时,即使使用引用运算符,它似乎也在制作它的副本。我这样说是因为每当我在一个类中调试和观察容器时,容器的大小就像预期的那样是 1,因为我将一个对象推入堆栈。但是,一旦我通过函数进入另一个类...该类将堆栈的大小更改回 0。直到我返回调用该函数的内容,然后它才返回 1。
是不是因为我继承自使用容器的类?接下来是我的下一个问题......继承是复制母类中的成员还是引用它们?我将尝试用最少的代码来解释这一点,所以请客气...
GAME.HPP
#ifndef GAME_HPP
#define GAME_HPP
#include <stack>
#include "GameState.hpp"
class Game
{
public:
Game();
~Game();
int playGame();
protected:
std::stack<GameState*>& getGStates();
private:
std::stack<GameState*> gameStates; //GameState is a abstract class (no implementation)
bool gameRunning;
};
#endif
GAME.CPP
int Game::playGame()
{
gameRunning = true;
SplashScreen sScreen; // SplashScreen inherits from GameState class
gameStates.push(std::move(&sScreen)); //move screen to stack without making a copy
// The stack size is now 1
while (gameRunning)
{
gameStates.top()->runState();
}
return 0;
}
std::stack<GameState*>& Game::getGStates()
{
return gameStates; //returns stack
}
GAMESTATE.HPP
#ifndef GAMESTATE_HPP
#define GAMESTATE_HPP
class GameState
{
public:
GameState(){};
~GameState(){};
virtual void runState() = 0;
virtual void resumeState() = 0;
virtual void pauseState() = 0;
virtual void update() = 0;
virtual void render() = 0;
};
#endif
我确实在SplashScreen 类中提供了大量的实现,但如果我删除它,问题仍然存在。所以现在为了简单起见,我只想说它和你在GameState 标题中看到的没有什么不同,但是有空白块和返回。我仍将显示runState() 位,但将其简化以限定问题范围。
SPLASHSCREEN.CPP
//obvious header includes above
void SplashScreen::runState()
{
std::cout << getGStates() << std::endl; //here the stack is 0
std::cin.get(); //getting char from input stream so program won't terminate so fast
return; //here I return to what invoke the runState() but stack becomes 1 again in the other class...Is a copy being returned by the getter ??
}
我想提一提的是SplashScreen 类确实继承自GameState 和Game 类。我从GameState 类继承,所以我可以将它用作我的SplashScreen 类的接口,我从Game 类继承,所以我可以使用getter 方法。
您可能会说为什么我不通过Game.cpp 中的函数runState() 直接通过引用传递。我可以并且它会起作用,但是有没有另一种方法可以做到这一点而不会使我的函数与参数混淆?我不想每次我需要一些东西时都添加一个参数。再说一次,如果我这样做,我的对象设计很差,对吗?请帮忙...
【问题讨论】:
-
SplashScreen sScreen; gameStates.push(std::move(&sScreen));- 不,不,不!这不是管理内存的安全方法。 -
@user2357112 请用您的知识启发我...什么是更好的方法? .:(∩´ ﹏ `∩):.
-
SplashScreen的定义范围一结束就会自毁。您需要动态分配它,可能使用new,或者重组您的程序,使其不必使用new。为什么SplashScreen继承自Game?闪屏不是游戏。听起来你还没有理解继承到底是什么。 -
该初始屏幕有自己的
GameState指针堆栈。您正在调用初始屏幕的getGStates方法,而不是您需要访问的对象的方法。启动画面甚至无法知道您想要的Game对象的getGStates方法。 -
@user2357112 哦哦,我之所以让
SplashScreen从游戏继承,是因为我将SplashScreen视为游戏的一部分,你知道它是第一个屏幕。我还读到 GameStates 就像您游戏中的单独程序/游戏,这就是我这样做的原因。我想我读的那篇文章不好吧?另外,我知道SplashScreen将在结束块处终止,但playGame实际上是我的结束块。我的程序运行来自其他状态类的状态,当游戏结束时它返回到playGame,然后终止循环。
标签: c++ c++11 inheritance