cross dependency/undefined refference problem

solution: that was dumb, i was compiling files in the wrong order



i'm not so great with forward declaration and cross dependencies:
error wrote:
$g++ unit.cpp
In function `unit::moveto(int, int)':
unit.cpp:(.text+0xba): undefined reference to `map::gettile(int, int)'
collect2: ld returned 1 exit status


from what i understand, i have forward-declared the map class, but not the gettile function, and i'm not sure how to fix that, or if forward-declaring is even what i should be doing in the first place. any and all help will be greatly appreciated.

unit.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef UNIT_H
#define UNIT_H

#include "globals.h"
#include "map.h"

enum dir {UL,U,UR,R,DR,D,DL,L};

class map;
class unit{
	int x;				//x coordinate of unit
	int y;				//y coordinate of unit
	char img;			//letter used to display the unit
	map* mptr;			//pointer to the map
	public:
		unit();
		unit(map*);
		~unit();
		bool move(dir);		//move in direction
		bool moveto(int,int);	//move to point (y,x)
		int* toimg();		//returns {y,x,(int)img}
};
#endif 


map.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef MAP_H
#define MAP_H

#include "globals.h"
#include "unit.h"

class unit;
class map{
	int mw;				//map width
	int mh;				//map height
	int sw;				//screen width
	int sh;				//screen height
	char** fplan;			//floor plan
	unit* guys;			//list of units
	public:
		map();
		~map();
		void populate();	//fill in the floor plan
		char gettile(int,int);	//get tile (y,x)
		char** draw(int,int);	//returns character array of the map centered around (y,x)
};
#endif 


unit.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include "unit.h"

unit::unit(){
	x=1;
	y=1;
	img='@';
}
unit::unit(map* m){
	x=1;
	y=1;
	img='@';
	mptr=m;
}
unit::~unit(){}
bool unit::move(dir d){
	switch(d){
		case UL:
			break;
		case U:
			break;
		case UR:
			break;
		case R:
			break;
		case DR:
			break;
		case D:
			break;
		case DL:
			break;
		case L:
			break;
		default:
			break;
	}
	return true;
}
bool unit::moveto(int b,int a){
	if((*mptr).gettile(b,a)==FLOOR){
		y=b;
		x=a;
		return true;
	}else{
		return false;
	}
}


map.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include "map.h"
#include "unit.h"

map::map(){
	mw=70;
	mh=30;
	sw=80;
	sh=24;
	fplan=new char*[mh];
	for(int j=0;j<mh;j++){
		fplan[j]=new char[mw];
	}
	populate();
}
map::~map(){
}
void map::populate(){
	for(int j=0;j<mh;j++){
		for(int i=0;i<mh;i++){
			if(j==0||i==0||j==mh-1||i==mw-1){
				fplan[j][i]=WALL;
			}else{
				fplan[j][i]=FLOOR;
			}
		}
	}
}
char map::gettile(int y,int x){
	if(y<0||x<0||y>=mh||x>=mw){
		return ' ';
	}else{
		return fplan[y][x];
	}
}
char** map::draw(int y,int x){
	char** ret=new char*[sh];
	int a=x-mw/2;
	int b=y-mh/2;
	for(int j=0;j<sh;j++){
		ret[j]=new char[sw];
		b++;
		a-=sw;
		for(int i=0;i<sw;i++){
			a++;
			ret[j][i]=gettile(b,a);
		}
	}
	return ret;
}
Last edited on
Try not to include Map.h and Unit.h in the headers, only include in the .cpp file. Give it a try.

At the moment you're including:
"unit.h" in "map.h"
"map.h" in "unit.h"
"unit.h" in "map.cpp"

So It's unable to link properly.
Last edited on
i'm still getting the same error.
edit: nvm, that along with fixing my compile order worked.
Last edited on
Are you making a tile engine for your game? Out of curiosity.
Last edited on
Linking and #includes are totally unrelated.

The problem is in the invocation of g++.

Either compile each source file individually to a .o using the -C parameter, or compile them all at once.

g++ map.cpp -C
g++ unit.cpp -C
g++ main.cpp -C
g++ map.o unit.o main.o -o myexecutable

or

g++ map.cpp unit.cpp main.cpp -o myexecutable
Topic archived. No new replies allowed.