从Java到C++我试图通过面向对象理解抽象。了解C++中的抽象
为了说明这个问题,我正在开发一个使用SFML库进行图形绘制的小游戏。然而,这个问题与此无关,只是将其视为背景信息。无论如何,游戏的工作方式是通过许多不同的状态进行处理。在这种情况下2:
菜单状态:游戏的菜单被绘制,游戏将从这里开始。
游戏状态:此状态控制游戏,将更新实体并绘制它们。
为了做到这一点,我已经创建了以下类:
GameStateManager.h
#ifndef GAMESTATEMANAGER_H
#define GAMESTATEMANAGER_H
#include <SFML/Graphics.hpp>
#include <iostream>
#include "GameState.h"
class GameStateManager
{
public:
// Constructor
GameStateManager();
// State variables
static const int NUMGAMESTATES = 2;
static const int MENUSTATE = 0;
static const int GAMESTATE = 1;
// Public Functions
void set_state(int state);
void update();
void draw(sf::RenderWindow &win);
void input(sf::Event event);
private:
// Array of gamestates
GameState game_states[];
// The current state
int current_state;
// Private functions
void load_state(int state);
void unload_state(int state);
};
#endif
GameState.h
#ifndef GAMESTATE_H
#define GAMESTATE_H
#include <iostream>
#include <SFML/Graphics.hpp>
#include "GameStateManager.h"
class GameState
{
protected:
GameStateManager gsm;
public:
virtual void init() = 0;
virtual void update() = 0;
virtual void draw(sf::RenderWindow &win) = 0;
virtual void input(sf::Event event) = 0;
};
#endif
现在你可能已经注意到了Array游戏状态管理器中的GameStates?这提供了一个我不明白的错误:零大小的数组。这是否意味着初始化需要在头文件中进行?进一步说到这一点,编译器提到了一个不允许的抽象类数组?
第二个问题是抽象GameState类中的字段gsm无法识别并引发另一个错误:缺少类型说明符。
现在让事情更复杂化,我有以下类:MenuState。这个类是为了扩展GameState。
MenuState.h
#ifndef MENUSTATE_H
#define MENUSTATE_H
#include "GameState.h"
class MenuState: public GameState
{
public:
MenuState(GameStateManager gsm);
void init();
void update();
void draw(sf::RenderWindow &win);
void input(sf::Event event);
private:
sf::Texture title_texture;
sf::Sprite title_sprite;
};
#endif
如前所述该类将控制游戏的菜单。如下
GameStateManager.cpp
/*
* GameState Manager will take care of the various states of the game.
* In particular there will be two states: Menu or Ingame. GameStateManager
* will load and unload each state as needed.
*
* Author: Ben Euden
* Date: 2/5/2014
*/
#include "GameStateManager.h"
// Class Constructor
GameStateManager::GameStateManager()
{
game_states = game_states[NUMGAMESTATES];
current_state = MENUSTATE;
load_state(current_state);
}
/*
* Load the current game by creating and initialising the state
* then storing it in the game_states array.
* @Param state The state we wish to load.
*/
void GameStateManager::load_state(int state)
{
if(state == MENUSTATE)
game_states[state] = MenuState(this);
//if(state == GAMESTATE)
//game_states[state] = MainGameState(this); // Not implemented yet.
}
/*
* Unload the state we loaded with load_state
*/
void GameStateManager::unload_state(int state)
{
game_states[state] = NULL;
}
void GameStateManager::set_state(int state)
{
unload_state(state);
current_state = state;
load_state(state);
}
void GameStateManager::update()
{
try{
game_states[current_state].update();
}
catch(int e)
{
std::cout << "Exception occured during update of game state" << e << std::endl;
}
}
void GameStateManager::draw(sf::RenderWindow &win)
{
try{
game_states[current_state].draw(&win);
}
catch(int e)
{
std::cout << "Exception occured when trying to draw gamestate: " << current_state << "Exception number: " << e << std::endl;
}
}
void GameStateManager::input(sf::Event event)
{
game_states[current_state].input(event);
}
而且MenuState:
/*
* This class extends the Game State header and will deal with the menu of the game
* this includes drawing the correct text to the screen, moving the selector and
* either exiting, bringing up about or starting the game.
*
* Author: Ben Euden
* Date: 2/5/2014
*/
#include "MenuState.h"
MenuState::MenuState(GameStateManager gsm)
{
gsm = gsm;
init();
}
void MenuState::init()
{
title_texture = sf::Texture();
title_texture.loadFromFile("sprites/Title.png");
title_sprite = sf::Sprite();
title_sprite.setTexture(title_texture);
title_sprite.setPosition(512, 200);
}
void MenuState::update(){}
void MenuState::draw(sf::RenderWindow &win)
{
win.draw(title_sprite);
}
void MenuState::input(sf::Event event)
{
}
请忽略inplemented方法和定位运动用作如下
实施GameStateManager完成。此时我开始尝试编译该项目(我使用Visual Studio)出现错误时。
现在明白,MainGameState尚未实现,但即使使用MenuState我确信我错过了一些至关重要的事情,因为我仍在学习C++。考虑到这一点,请原谅任何破坏公约等,我正在学习,所以随时纠正我,我更好地学习正确的方式,而不是养成坏习惯。
总结,我想知道为什么我收到以下错误:
protected:
GameStateManager gsm;
这将产生错误:缺少“;”在gsm之前。
GameState game_states[];
产生以下错误:零大小数组,不允许抽象类数组。
我相信如果我解决了这些问题,其余的人都会自行解决。
谢谢你的耐心,时间和对此的帮助。
Euden
那么,你有一对圆形包括,所以这不会帮助... –
如果你可以足够的指出这些我会很感激它(这可能是一个错误,由于编码延迟到晚上-_-) –