Archived

This topic is now archived and is closed to further replies.

Kranar

Problem with classes/syntax

Recommended Posts

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

Share this post


Link to post
Share on other sites
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!}

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster

#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 nice

extern 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...

Share this post


Link to post
Share on other sites
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_H

class 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_H

class 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_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;
};

#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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites