從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
那麼,你有一對圓形包括,所以這不會幫助... –
如果你可以足夠的指出這些我會很感激它(這可能是一個錯誤,由於編碼延遲到晚上-_-) –