由于继承而堆栈返回副本?

时间:2016-08-28 03:06:28

标签: c++ c++11 inheritance

我试图让我的堆栈容器适配器通过引用从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类确实继承自GameStateGame类。我继承了GameState类,所以我可以将它用作SplashScreen类的接口,并且我从Game类继承,所以我可以使用getter方法。

你可能会说我为什么不通过runState()中的Game.cpp函数来引用。我可以而且它可以工作,但有没有其他方法可以做到这一点而不会使我的函数与参数混乱?我不想在每次需要时添加参数。如果我这样做,我的对象设计很差,对吧?请帮忙......

1 个答案:

答案 0 :(得分:1)

您提到SplashScreen继承自Game。 因此,以下代码:

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实例对象的堆栈,而不是初始Game实例对象。换句话说,您打印的堆栈与您将SplashScreen对象推送到的堆栈不同,甚至是它的副本,而是完全不相关的GameState堆栈。

您的问题是:继承不是推理GameSplashScreen之间关系的正确方法。继承主要是模型“是类之间的一种”关系,看起来SplashScreen可能不是一种游戏。您想要表示的关系类型是一种使用关系,通过引用您将要使用的对象或将其作为参数传递给callstack中的某个参数来表示。

如果你需要访问游戏,你应该:

  1. 将其添加为SplashScreen类中的成员变量,例如

    //Splashscreen.h
    class SplashScreen : public GameState {
        public:
        SplashScreen(Game& game)
        : m_game(game) {
        }
    
        ...    
    
        private:
        Game& m_game;
    }
    
    //SplashScreen.cpp
    void SplashScreen::runState()
    {
        std::cout << m_game.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 ??
    }
    
  2. 或将其作为参数传递给runState方法,例如

    void SplashScreen::runState(Game& game)
    {
        std::cout << game.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 ??
    }