PDA

View Full Version : Pure virtual functions, vectors without types, and undeclared classes?


cypher543
11-24-2006, 08:57 AM
Well, as you can see from the title, I'm having a bit of trouble here... I'm trying to implement a GameState system so I can easily switch between the menu, the game, the pause screen, and the intro sequence. But, I get a ton of errors, all of which I just don't understand how to fix. Some related to creating a vector without a type (even though a type is specified), others are about undefined classes (which are defined) and others are about pure virtual functions and abstract types.

I'm new to the C++ scene (well, kind of... I just don't understand some of the OO aspects yet), so forgive me if these are caused by really stupid mistakes on my part.

You can download the source here: http://www.cypherspace.info/gamestate.tar.gz

The output of make is:
$ make
g++ -Iinclude -o ghost main.cpp GameManager.cpp IntroState.cpp MenuState.cpp PlayState.cpp PauseState.cpp
include/GameState.h:12: error: ‘GameManager’ has not been declared
include/GameState.h:13: error: ‘GameManager’ has not been declared
include/GameState.h:14: error: ‘GameManager’ has not been declared
include/GameState.h:15: error: ‘GameManager’ has not been declared
include/GameState.h: In member function ‘void GameState::changeState(int*, GameState*)’:
include/GameState.h:16: error: request for member ‘changeState’ in ‘* game’, which is of non-class type ‘int’
include/GameManager.h: At global scope:
include/GameManager.h:20: error: ISO C++ forbids declaration of ‘vector’ with no type
include/GameManager.h:20: error: expected ‘;’ before ‘<’ token
include/IntroState.h:21: error: cannot declare variable ‘IntroState::m_IntroState’ to be of abstract type ‘IntroState’
include/IntroState.h:6: note: because the following virtual functions are pure within ‘IntroState’:
include/GameState.h:12: note: virtual void GameState::handleEvents(int*)
include/GameState.h:13: note: virtual void GameState::update(int*)
include/GameState.h:14: note: virtual void GameState::draw(int*)
main.cpp: In function ‘int main(int, char**)’:
main.cpp:7: error: request for member ‘init’ in ‘game’, which is of non-class type ‘GameManager*’
main.cpp:8: error: request for member ‘changeState’ in ‘game’, which is of non-class type ‘GameManager*’
main.cpp:10: error: request for member ‘isRunning’ in ‘game’, which is of non-class type ‘GameManager*’
main.cpp:11: error: request for member ‘handleEvents’ in ‘game’, which is of non-class type ‘GameManager*’
main.cpp:13: error: request for member ‘draw’ in ‘game’, which is of non-class type ‘GameManager*’
main.cpp:16: error: request for member ‘cleanup’ in ‘game’, which is of non-class type ‘GameManager*’
include/GameState.h:12: error: ‘GameManager’ has not been declared
include/GameState.h:13: error: ‘GameManager’ has not been declared
include/GameState.h:14: error: ‘GameManager’ has not been declared
include/GameState.h:15: error: ‘GameManager’ has not been declared
include/GameState.h: In member function ‘void GameState::changeState(int*, GameState*)’:
include/GameState.h:16: error: request for member ‘changeState’ in ‘* game’, which is of non-class type ‘int’
include/GameManager.h: At global scope:
include/GameManager.h:20: error: ISO C++ forbids declaration of ‘vector’ with no type
include/GameManager.h:20: error: expected ‘;’ before ‘<’ token
GameManager.cpp: In member function ‘void GameManager::cleanup()’:
GameManager.cpp:14: error: ‘states’ was not declared in this scope
GameManager.cpp: In member function ‘void GameManager::changeState(GameState*)’:
GameManager.cpp:25: error: ‘states’ was not declared in this scope
GameManager.cpp:31: error: ‘states’ was not declared in this scope
GameManager.cpp: In member function ‘void GameManager::pushState(GameState*)’:
GameManager.cpp:38: error: ‘states’ was not declared in this scope
GameManager.cpp:43: error: ‘states’ was not declared in this scope
GameManager.cpp: In member function ‘void GameManager::popState()’:
GameManager.cpp:50: error: ‘states’ was not declared in this scope
GameManager.cpp:56: error: ‘states’ was not declared in this scope
GameManager.cpp: In member function ‘void GameManager::handleEvents()’:
GameManager.cpp:65: error: ‘states’ was not declared in this scope
GameManager.cpp: In member function ‘void GameManager::update()’:
GameManager.cpp:71: error: ‘states’ was not declared in this scope
GameManager.cpp: In member function ‘void GameManager::draw()’:
GameManager.cpp:77: error: ‘states’ was not declared in this scope
include/GameState.h:12: error: ‘GameManager’ has not been declared
include/GameState.h:13: error: ‘GameManager’ has not been declared
include/GameState.h:14: error: ‘GameManager’ has not been declared
include/GameState.h:15: error: ‘GameManager’ has not been declared
include/GameState.h: In member function ‘void GameState::changeState(int*, GameState*)’:
include/GameState.h:16: error: request for member ‘changeState’ in ‘* game’, which is of non-class type ‘int’
include/GameManager.h: At global scope:
include/GameManager.h:20: error: ISO C++ forbids declaration of ‘vector’ with no type
include/GameManager.h:20: error: expected ‘;’ before ‘<’ token
include/IntroState.h:21: error: cannot declare variable ‘IntroState::m_IntroState’ to be of abstract type ‘IntroState’
include/IntroState.h:6: note: because the following virtual functions are pure within ‘IntroState’:
include/GameState.h:12: note: virtual void GameState::handleEvents(int*)
include/GameState.h:13: note: virtual void GameState::update(int*)
include/GameState.h:14: note: virtual void GameState::draw(int*)
include/MenuState.h:21: error: cannot declare variable ‘MenuState::m_MenuState’ to be of abstract type ‘MenuState’
include/MenuState.h:6: note: because the following virtual functions are pure within ‘MenuState’:
include/GameState.h:12: note: virtual void GameState::handleEvents(int*)
include/GameState.h:13: note: virtual void GameState::update(int*)
include/GameState.h:14: note: virtual void GameState::draw(int*)
IntroState.cpp:7: error: cannot declare variable ‘IntroState::m_IntroState’ to be of abstract type ‘IntroState’
include/IntroState.h:6: note: since type ‘IntroState’ has pure virtual functions
IntroState.cpp:24: error: no ‘void IntroState::pesume()’ member function declared in class ‘IntroState’
include/GameState.h:12: error: ‘GameManager’ has not been declared
include/GameState.h:13: error: ‘GameManager’ has not been declared
include/GameState.h:14: error: ‘GameManager’ has not been declared
include/GameState.h:15: error: ‘GameManager’ has not been declared
include/GameState.h: In member function ‘void GameState::changeState(int*, GameState*)’:
include/GameState.h:16: error: request for member ‘changeState’ in ‘* game’, which is of non-class type ‘int’
include/GameManager.h: At global scope:
include/GameManager.h:20: error: ISO C++ forbids declaration of ‘vector’ with no type
include/GameManager.h:20: error: expected ‘;’ before ‘<’ token
include/MenuState.h:21: error: cannot declare variable ‘MenuState::m_MenuState’ to be of abstract type ‘MenuState’
include/MenuState.h:6: note: because the following virtual functions are pure within ‘MenuState’:
include/GameState.h:12: note: virtual void GameState::handleEvents(int*)
include/GameState.h:13: note: virtual void GameState::update(int*)
include/GameState.h:14: note: virtual void GameState::draw(int*)
include/PlayState.h:21: error: cannot declare variable ‘PlayState::m_PlayState’ to be of abstract type ‘PlayState’
include/PlayState.h:6: note: because the following virtual functions are pure within ‘PlayState’:
include/GameState.h:12: note: virtual void GameState::handleEvents(int*)
include/GameState.h:13: note: virtual void GameState::update(int*)
include/GameState.h:14: note: virtual void GameState::draw(int*)
MenuState.cpp:7: error: cannot declare variable ‘MenuState::m_MenuState’ to be of abstract type ‘MenuState’
include/MenuState.h:6: note: since type ‘MenuState’ has pure virtual functions
include/GameState.h:12: error: ‘GameManager’ has not been declared
include/GameState.h:13: error: ‘GameManager’ has not been declared
include/GameState.h:14: error: ‘GameManager’ has not been declared
include/GameState.h:15: error: ‘GameManager’ has not been declared
include/GameState.h: In member function ‘void GameState::changeState(int*, GameState*)’:
include/GameState.h:16: error: request for member ‘changeState’ in ‘* game’, which is of non-class type ‘int’
include/GameManager.h: At global scope:
include/GameManager.h:20: error: ISO C++ forbids declaration of ‘vector’ with no type
include/GameManager.h:20: error: expected ‘;’ before ‘<’ token
include/PauseState.h:21: error: cannot declare variable ‘PauseState::m_PauseState’ to be of abstract type ‘PauseState’
include/PauseState.h:6: note: because the following virtual functions are pure within ‘PauseState’:
include/GameState.h:12: note: virtual void GameState::handleEvents(int*)
include/GameState.h:13: note: virtual void GameState::update(int*)
include/GameState.h:14: note: virtual void GameState::draw(int*)
include/PlayState.h:21: error: cannot declare variable ‘PlayState::m_PlayState’ to be of abstract type ‘PlayState’
include/PlayState.h:6: note: because the following virtual functions are pure within ‘PlayState’:
include/GameState.h:12: note: virtual void GameState::handleEvents(int*)
include/GameState.h:13: note: virtual void GameState::update(int*)
include/GameState.h:14: note: virtual void GameState::draw(int*)
PlayState.cpp:7: error: cannot declare variable ‘PlayState::m_PlayState’ to be of abstract type ‘PlayState’
include/PlayState.h:6: note: since type ‘PlayState’ has pure virtual functions
include/GameState.h:12: error: ‘GameManager’ has not been declared
include/GameState.h:13: error: ‘GameManager’ has not been declared
include/GameState.h:14: error: ‘GameManager’ has not been declared
include/GameState.h:15: error: ‘GameManager’ has not been declared
include/GameState.h: In member function ‘void GameState::changeState(int*, GameState*)’:
include/GameState.h:16: error: request for member ‘changeState’ in ‘* game’, which is of non-class type ‘int’
include/GameManager.h: At global scope:
include/GameManager.h:20: error: ISO C++ forbids declaration of ‘vector’ with no type
include/GameManager.h:20: error: expected ‘;’ before ‘<’ token
include/PauseState.h:21: error: cannot declare variable ‘PauseState::m_PauseState’ to be of abstract type ‘PauseState’
include/PauseState.h:6: note: because the following virtual functions are pure within ‘PauseState’:
include/GameState.h:12: note: virtual void GameState::handleEvents(int*)
include/GameState.h:13: note: virtual void GameState::update(int*)
include/GameState.h:14: note: virtual void GameState::draw(int*)
include/MenuState.h:21: error: cannot declare variable ‘MenuState::m_MenuState’ to be of abstract type ‘MenuState’
include/MenuState.h:6: note: because the following virtual functions are pure within ‘MenuState’:
include/GameState.h:12: note: virtual void GameState::handleEvents(int*)
include/GameState.h:13: note: virtual void GameState::update(int*)
include/GameState.h:14: note: virtual void GameState::draw(int*)
PauseState.cpp:7: error: cannot declare variable ‘PauseState::m_PauseState’ to be of abstract type ‘PauseState’
include/PauseState.h:6: note: since type ‘PauseState’ has pure virtual functions
make: *** [all] Error 1
Can anyone help?

Jare
11-24-2006, 10:49 AM
You have a circular include: GameState.h includes GameManager.h, and viceversa. That's bad stuff, and in this case, completely unnecessary. Just add a forward-declaration for GameManager in GameState.h (just like you did for GameState in GameManager.h), and remove both #include sentences from both headers (you will need the #include in the .cpp files).

#ifndef GAMEMANAGER_H
#define GAMEMANAGER_H

class GameState;

class GameManager {
...
};

#endif

#ifndef GAMESTATE_H
#define GAMESTATE_H

class GameManager;

class GameState {
...
};
#endif

cypher543
11-24-2006, 10:56 AM
Thanks. I knew it was going to be something silly like that. That got rid of the pure virtual function errors, but now I get this:
$ make
g++ -Iinclude -o ghost main.cpp GameManager.cpp IntroState.cpp MenuState.cpp PlayState.cpp PauseState.cpp
include/GameManager.h:18: error: ISO C++ forbids declaration of ‘vector’ with no type
include/GameManager.h:18: error: expected ‘;’ before ‘<’ token
main.cpp: In function ‘int main(int, char**)’:
main.cpp:7: error: request for member ‘init’ in ‘game’, which is of non-class type ‘GameManager*’
main.cpp:8: error: request for member ‘changeState’ in ‘game’, which is of non-class type ‘GameManager*’
main.cpp:10: error: request for member ‘isRunning’ in ‘game’, which is of non-class type ‘GameManager*’
main.cpp:11: error: request for member ‘handleEvents’ in ‘game’, which is of non-class type ‘GameManager*’
main.cpp:13: error: request for member ‘draw’ in ‘game’, which is of non-class type ‘GameManager*’
main.cpp:16: error: request for member ‘cleanup’ in ‘game’, which is of non-class type ‘GameManager*’
include/GameManager.h:18: error: ISO C++ forbids declaration of ‘vector’ with no type
include/GameManager.h:18: error: expected ‘;’ before ‘<’ token
GameManager.cpp: In member function ‘void GameManager::cleanup()’:
GameManager.cpp:14: error: ‘states’ was not declared in this scope
GameManager.cpp: In member function ‘void GameManager::changeState(GameState*)’:
GameManager.cpp:25: error: ‘states’ was not declared in this scope
GameManager.cpp:31: error: ‘states’ was not declared in this scope
GameManager.cpp: In member function ‘void GameManager::pushState(GameState*)’:
GameManager.cpp:38: error: ‘states’ was not declared in this scope
GameManager.cpp:43: error: ‘states’ was not declared in this scope
GameManager.cpp: In member function ‘void GameManager::popState()’:
GameManager.cpp:50: error: ‘states’ was not declared in this scope
GameManager.cpp:56: error: ‘states’ was not declared in this scope
GameManager.cpp: In member function ‘void GameManager::handleEvents()’:
GameManager.cpp:65: error: ‘states’ was not declared in this scope
GameManager.cpp: In member function ‘void GameManager::update()’:
GameManager.cpp:71: error: ‘states’ was not declared in this scope
GameManager.cpp: In member function ‘void GameManager::draw()’:
GameManager.cpp:77: error: ‘states’ was not declared in this scope
include/GameManager.h:18: error: ISO C++ forbids declaration of ‘vector’ with no type
include/GameManager.h:18: error: expected ‘;’ before ‘<’ token
IntroState.cpp:24: error: no ‘void IntroState::pesume()’ member function declared in class ‘IntroState’
include/GameManager.h:18: error: ISO C++ forbids declaration of ‘vector’ with no type
include/GameManager.h:18: error: expected ‘;’ before ‘<’ token
include/GameManager.h:18: error: ISO C++ forbids declaration of ‘vector’ with no type
include/GameManager.h:18: error: expected ‘;’ before ‘<’ token
include/GameManager.h:18: error: ISO C++ forbids declaration of ‘vector’ with no type
include/GameManager.h:18: error: expected ‘;’ before ‘<’ token
make: *** [all] Error 1
Looks like I still have class and vector type problems. :(

.oisyn
11-24-2006, 11:55 AM
You would probably get more response if you placed the relevant bits of code in your post. Not too many people are willing to download and look through an entire codebase :)

cypher543
11-24-2006, 12:33 PM
Alright, fine...

main.cpp:
#include "GameManager.h"
#include "IntroState.h"

int main(int argc, char* argv[]) {
GameManager* game;

game.init();
game.changeState(IntroState::instance());

while (game.isRunning) {
game.handleEvents();
// game.Update(); - I don't think I'll need this...
game.draw();
}

game.cleanup();
return 0;
}
GameManager.cpp:
#include <stdio.h>

#include "GameManager.h"

#include "GameState.h"



void GameManager::init()

{

isRunning = true;

printf("CGameEngine Init\n");

}

void GameManager::cleanup()

{

// cleanup the all states

while ( !states.empty() ) {

states.back()->cleanup();

states.pop_back();

}



printf("GameManager Cleanup\n");

}



void GameManager::changeState(GameState* state)

{

// cleanup the current state

if ( !states.empty() ) {

states.back()->cleanup();

states.pop_back();

}



// store and init the new state

states.push_back(state);

states.back()->init();

}



void GameManager::pushState(GameState* state)

{

// pause current state

if ( !states.empty() ) {

states.back()->pause();

}



// store and init the new state

states.push_back(state);

states.back()->init();

}



void GameManager::popState()

{

// cleanup the current state

if ( !states.empty() ) {

states.back()->cleanup();

states.pop_back();

}



// resume previous state

if ( !states.empty() ) {

states.back()->resume();

}

}





void GameManager::handleEvents()

{

// let the state handle events

states.back()->handleEvents(this);

}



void GameManager::update()

{

// let the state update the game

states.back()->update(this);

}



void GameManager::draw()

{

// let the state draw the screen

states.back()->draw(this);

}
GameManager.h:
#ifndef GAMEMANAGER_H

#define GAMEMANAGER_H

class GameState;

class GameManager {
public:
void init();
void cleanup();
void changeState(GameState* state);
void pushState(GameState* state);
void popState();
void handleEvents();
void update();
void draw();
void quit() { isRunning = false; }
private:
vector<GameState*> states;
bool isRunning;
};

#endif

Reedbeta
11-24-2006, 12:38 PM
include/GameManager.h:18: error: ISO C++ forbids declaration of ‘vector’ with no type
include/GameManager.h:18: error: expected ‘;’ before ‘<’ token


You haven't #included <vector> in GameManager.h, so when it's trying to compile it, it has no idea what the word "vector" means. Add the #include <vector> to the top of the file. Also, you need to write std::vector, since the vector class is in the 'std' namespace.


main.cpp: In function ‘int main(int, char**)’:
main.cpp:7: error: request for member ‘init’ in ‘game’, which is of non-class type ‘GameManager*’
main.cpp:8: error: request for member ‘changeState’ in ‘game’, which is of non-class type ‘GameManager*’
main.cpp:10: error: request for member ‘isRunning’ in ‘game’, which is of non-class type ‘GameManager*’
main.cpp:11: error: request for member ‘handleEvents’ in ‘game’, which is of non-class type ‘GameManager*’
main.cpp:13: error: request for member ‘draw’ in ‘game’, which is of non-class type ‘GameManager*’
main.cpp:16: error: request for member ‘cleanup’ in ‘game’, which is of non-class type ‘GameManager*’


You've declared 'game' as type GameManager*, which is a pointer to a GameManager. Hence, you would need to access its members like game->init() rather than game.init(). However, you haven't initialized the pointer anyplace, so it's currently pointing to garbage. I'm guessing you really just wanted to declare a GameManager object, not a GameManager*. So just remove the * and it should work.


GameManager.cpp: In member function ‘void GameManager::cleanup()’:
GameManager.cpp:14: error: ‘states’ was not declared in this scope
...


This is caused by the problem with the vector declaration; fix that and these errors should also go away.


GameManager.cpp: In member function ‘void IntroState.cpp:24: error: no ‘void IntroState::pesume()’ member function declared in class ‘IntroState’


Looks like you made a typo, 'pesume'.

cypher543
11-24-2006, 12:56 PM
I just knew it would be little things like that. Thanks for your help!