Problem with classes/syntax

Started by
8 comments, last by Kranar 20 years, 6 months ago
I have 2 classes and 4 files as follows: TileMap.cpp

#include "tilemap.h"

TileMap::TileMap(void) {
	tileX		= 16;
	tileY		= 16;
	id			= -1;
	charLayer	= 1;
}

TileMap::~TileMap(void){}

void TileMap::ShowMap(int cX, int cY) {
	for(int x = 0; x < int(map.size()); x++) {
		for(int y = 0; y < int(map[x].size()); y++) {
			for(int z = 0; z < int(map[x][y].size()); z++) {
				if(y >= 0 && z >= 0 && y < int(map[x].size()) &&
					z < int(map[x][y].size()) &&
					map[x][y][z] < int(tileSet.size()) + 1) {
					tileSet[map[x][y][z] - 1]->Show(cX, cY);
				}
			}
		}
	}
}
Tilemap.h

class TileMap {
public:
	TileMap(void);
	~TileMap(void);
	void ShowMap(int cX, int cY);
};
System.h

#pragma once
#include "externals.h"

class System {
public:
	System(void);
	~System(void);
	void Init(int resX, int resY);
	void Draw(BITMAP *sprite, int x, int y, int alpha = -1);
	void Flip();
	int getResX();
	int getResY();
private:
	int			resX, resY;
	BITMAP		*predraw;
};
System.cpp

#include "system.h"

System::System(void){}

System::~System(void){}

void System::Init(int resX, int resY) {
	allegro_init();
	install_keyboard();
	set_color_depth(32);
	set_gfx_mode(GFX_AUTODETECT_WINDOWED, resX, resY, 0, 0);
	predraw = create_bitmap(resX, resY);
	(*this).resX = resX;
	(*this).resY = resY;
}

void System::Draw(BITMAP *sprite, int x, int y, int alpha) {
	draw_sprite(predraw, sprite, x, y);
}

void System::Flip() {
	draw_sprite(screen, predraw, 0, 0);
	clear(predraw);
}

int System::getResX() {
	return resX;
}

int System::getResY() {
	return resY;
}
And an external.h with all my includes in it. The thing is, when I compile it like this, I get a BOATLOAD of syntax errors from God knows where. Syntax errors like I''m missing a '')'' or '';''. Now I don''t see how I can be missing any of these, infact I know I''m not since whenever I include all the code within the definition of the class they compile perfectly. Like if I did something like this it will work.

class someClass {
  int add(int a, int b) {
     return a + b;
  }
};
But this will give me all these syntax errors.

class someClass {
  int add(int a, int b);
};

int someClass::add(int a, int b) {
  return a + b;
}
Any idea why this happens? I''m using MSVC++ .NET
Advertisement
How does your external.h look like? And did you remember to put those code-guard #ifndef, #define in your header files to make sure they''re not getting defined twice?




--{You fight like a dairy farmer!}

--{You fight like a dairy farmer!}

Also, post the errors you get.

How appropriate. You fight like a cow.
Sounds a lot like double inclusion

#ifndef _WHATEVER_H_
#define _WAHTEVER_H_

// whatever.h code

#endif

Wizza Wuzza?
My externals.h file looks like this:

#include <allegro.h>#include <winalleg.h>#include <string>#include <vector>#include "System.h"#include "Tile.h"#include "TileMap.h"using namespace std;extern class System Manager;


I don''t know how to use #ifndef #define

Anyone care to point me in the right direction?

The errors I get are like 200 syntax errors about me missing a semi colon or a bracket followed by a final error that says end of file not expected.
// in header files#ifndef MYHEADERFILE_H#define MYHEADERFILE_H// class declarations#endif
#ifndef HEADERFILENAME_H#define HEADERFILENAME_H#include <allegro.h>#include <winalleg.h>#include <string>#include <vector>#include "System.h"#include "Tile.h"#include "TileMap.h"using namespace std; // <<-- this is not niceextern class System Manager;#endif


put these #ifndef #define as ive done here in all your header files, they should be put at the top of the file and the #endif should be put at the last row of the file.

#ifndef < if not defined, if statement begins
#define < define identifier
#endif < end if statement

so the #ifndef checks if whatever comes after it is defined in this case HEADERFILENAME_H, if it is the compiler skips the code until it reaches #endif, basically it skips the whole file as ive put it at the last row. If HEADERFILENAME_H is not defined then the #define defines it...
Yep, same problem still. I added that to all my .h files so that it now looks like this:

TileMap.h

#pragma once#include "externals.h"#ifndef TILEMAP_H#define TILEMAP_Hclass TileMap {public:	TileMap(void);	~TileMap(void);	void ShowMap(int cX, int cY);	void addTile(Tile* newTile);	void addLayer(vector<vector<int> > layer);	void LoadTileSet(char* file, int tileX = 16, int tileY = 16);	void LoadMap(int id);	void SaveMap();private:	int	tileX;		// base width of tiles	int tileY;		// base height of tiles	int	id;			// unique map id number	int	charLayer;	// layer characters are drawn on	vector<vector<vector<int> > > map;		 // layerXhorizontalXvertical	vector<Tile*>				  tileSet;	 // tile set used for the map};#endif


TileMap.cpp

#include "Tilemap.h"TileMap::TileMap(void) {	tileX		= 16;	tileY		= 16;	id			= -1;	charLayer	= 1;}TileMap::~TileMap(void){}void TileMap::ShowMap(int cX, int cY) {	for(int x = 0; x < int(map.size()); x++) {		for(int y = 0; y < int(map[x].size()); y++) {			for(int z = 0; z < int(map[x][y].size()); z++) {				if(y >= 0 && z >= 0 && y < int(map[x].size()) &&					z < int(map[x][y].size()) &&					map[x][y][z] < int(tileSet.size()) + 1) {					tileSet[map[x][y][z] - 1]->Show(y*tileX + cX - map[x].size()*tileX/2,						z*tileY + cY - map[x][y].size()*tileY/2);				}			}		}	}}void TileMap::addTile(Tile* newTile) {	tileSet.push_back(newTile);}void TileMap::addLayer(vector<vector<int> > layer) {	map.push_back(layer);}void TileMap::LoadTileSet(char* file, int tileX, int tileY) {	(*this).tileX = tileX;	(*this).tileY = tileY;	BITMAP *set = load_pcx(file, NULL);	BITMAP *tileBuffer = create_bitmap(tileX, tileY);	Tile *nextTile;	for(int x = 0; x < int(set->w / tileY); x++) {		for(int y = 0; y < int(set->h / tileX); y++) {			nextTile = new Tile;			blit(set, tileBuffer, x*tileX, y*tileY, 0, 0, tileX, tileY);			nextTile->addFrame(tileBuffer);			addTile(nextTile);		}	}}void TileMap::LoadMap(int id) {}void TileMap::SaveMap() {}


Tile.h

#pragma once#include "externals.h"#ifndef TILE_H#define TILE_Hclass Tile {public:	Tile(void);	~Tile(void);	void Show(int x, int y, int alpha = -1);	void addFrame(char* path);	void addFrame(BITMAP *t);	int getFrames();	int getCurrentFrame();private:	int				resX, resY;	vector<BITMAP*>	bitmap;	int				currentFrame;	int				timer;	int				alpha;};#endif


Tile.cpp

#include "Tile.h"Tile::Tile(void) {	currentFrame = 0;	timer = 0;	alpha = 255;};Tile::~Tile(void) {	for(int x = 0; x < int(bitmap.size()); x++) {		destroy_bitmap(bitmap[x]);	}}void Tile::Show(int x, int y, int alpha) {	if(bitmap.size() > 0) {		Manager.Draw(bitmap[currentFrame], x, y);	}}void Tile::addFrame(char* path) {	BITMAP *t = load_pcx(path, NULL);	if(t != NULL) {		resX = t->w; resY = t->h;		bitmap.push_back(t);	}}void Tile::addFrame(BITMAP *t) {	BITMAP *x = create_bitmap(t->w, t->h);	draw_sprite(x, t, 0, 0);	if(t != NULL) {		resX = x->w; resY = x->h;		bitmap.push_back(x);	}}int Tile::getFrames() {	return int(bitmap.size());}int Tile::getCurrentFrame() {	return currentFrame;}


System.h

#pragma once#include "externals.h"#ifndef SYSTEM_H#define SYSTEM_Hclass System {public:	System(void);	~System(void);	void Init(int resX, int resY);	void Draw(BITMAP *sprite, int x, int y, int alpha = -1);	void Flip();	int getResX();	int getResY();private:	int			resX, resY;	BITMAP		*predraw;};#endif


System.cpp

#include "System.h"System::System(void){}System::~System(void){}void System::Init(int resX, int resY) {	allegro_init();	install_keyboard();	set_color_depth(32);	set_gfx_mode(GFX_AUTODETECT_WINDOWED, resX, resY, 0, 0);	predraw = create_bitmap(resX, resY);	(*this).resX = resX;	(*this).resY = resY;}void System::Draw(BITMAP *sprite, int x, int y, int alpha) {	draw_sprite(predraw, sprite, x, y);}void System::Flip() {	draw_sprite(screen, predraw, 0, 0);	clear(predraw);}int System::getResX() {	return resX;}int System::getResY() {	return resY;}


Ultraverse.cpp

#include "externals.h"#include <math.h>#include <time.h>class System Manager;int main(void) {	Manager.Init(640, 480);	TileMap map;	map.LoadTileSet("CHIPSET.PCX");	vector<int> row;	vector<vector<int> > mapr;	srand( (unsigned)time( NULL ) );	for(int q = 0; q < 100; q++) {		row.clear();		for(int w = 0; w < 100; w++) {			row.push_back(1);		}		mapr.push_back(row);	}	map.addLayer(mapr);	mapr.clear();	for(int q = 0; q < 100; q++) {		row.clear();		for(int w = 0; w < 100; w++) {			row.push_back((rand() % 480) + 1);		}		mapr.push_back(row);	}	map.addLayer(mapr);	int x = 800/2, y = 600/2;	while(!key[KEY_ESC]) {		if(key[KEY_LEFT]) {			x-=2;		}		if(key[KEY_RIGHT]) {			x+=2;		}		if(key[KEY_UP]) {			y-=2;		}		if(key[KEY_DOWN]) {			y+=2;		}		map.ShowMap(x, y);		Manager.Flip();		textprintf(screen, font, 0, 0, 0xFFFFFF, "X: %d Y: %d", x, y);	}	return 0;}END_OF_MAIN();


Externals.h

#ifndef EXTERNAL_H#define EXTERNAL_H#include <allegro.h>#include <winalleg.h>#include <string>#include <vector>#include "System.h"#include "TileMap.h"#include "Tile.h"using namespace std;extern class System Manager;#endif


And that''s the entire project.

I get these errors, but like multiple instances of them:

c:\Generation-X\The Ultraverse\TileMap.h(12): error C2061: syntax error : identifier ''Tile''

c:\Generation-X\The Ultraverse\TileMap.h(13): error C2061: syntax error : identifier ''vector''

c:\Generation-X\The Ultraverse\TileMap.h(23): error C2143: syntax error : missing '';'' before ''<''

c:\Generation-X\The Ultraverse\TileMap.h(24): error C2238: unexpected token(s) preceding '';''

c:\Generation-X\The Ultraverse\Tile.h(18): error C2501: ''Tile::vector'' : missing storage-class or type specifiers

c:\Generation-X\The Ultraverse\TileMap.h(23): error C2501: ''TileMap::vector'' : missing storage-class or type specifiers

c:\Generation-X\The Ultraverse\The Ultraverse.cpp(21): error C2660: ''TileMap::addLayer'' : function does not take 1 parameters

No idea what''s going on.
Okay. First, here''s what''s going on.

* System.cpp includes System.h

* System.h includes Externals.h

* Externals.h includes System.h - BUT the inclusion guard in System.h prevents anything from actually being put in

* Externals.h includes Tilemap.h

* Tilemap.h includes Externals.h - BUT the inclusion guard in Externals.h prevents anything from actually being put in, including Tile.h

The solution: Don''t use monolithic header files like Externals.h. They''re stupid. Follow the standard rules for inclusion:

* If a class is used only as a reference or pointer by another class, declare it as "class A;" in the other class'' header
* If a class is used as a datatype or is inherited from by another class, include its header in the other class'' header.

How appropriate. You fight like a cow.
Awesome, works now.

This topic is closed to new replies.

Advertisement