Sign in to follow this  
Amatamazi

Cannot find classes / source files

Recommended Posts

I imagine this problem has something to do with my lack of understanding of using source files. I'm using Allegro and Dev-C++. When I compile the program, player.cpp cannot find class CTileMap's TileMap. I've tried declaring CObject as a friend of CTileMap, moving code around, google and forums for a week and still nothing. Ive stripped it down to what you should need to help. Thanks! main.cpp
#include <allegro.h>
#include "tilemap.h"
#include "player.h"


CTileMap TileMap;
CObject player, enemy[2];


int main(){    
}
END_OF_MAIN();





Player.cpp with errors commented

#include "player.h"

void CObject::Collision() {

            if (TileMap.begin[2]+10 != 30)     // `TileMap' undeclared (first use this function) 
            {
                   //do stuff

            }
}





player.h
#ifndef __PLAYER_H__
#define __PLAYER_H__

#include <allegro.h>
#include <string>
using namespace std;
#include "tilemap.h"


class CObject {
      public:
             void Collision();
             
};

#endif





tilemap.h
#ifndef TILEMAP_H_
#define TILEMAP_H_

#include <allegro.h>
#include <fstream>
using namespace std;
#include "player.h"


extern int width;
extern int height;

class CTileMap {

   public:
      int begin[3];

};

#endif





[Edited by - Amatamazi on July 27, 2008 5:34:25 AM]

Share this post


Link to post
Share on other sites
Theres a circular dependency in there (tilemap.h includes player.h which includes tilemap.h).

The easiest way around this would be to use a "Master" header file. The default in VC++ is usually the precompiled header, stdafx.h.

Instead of including allegro's header in every file, just include it in the top file and include that in every file. Perhaps this isn't clear enough, I'll try to code it in:



#ifndef _MASTER_H_INCLUDED_
#define _MASTER_H_INCLUDED_

#include <allegro.h>

using namespace std;

#include "tilemap.h"
#include "player.h"
//etc



and include this in all of your *.cpp files. Hope that makes sense.

Share this post


Link to post
Share on other sites
I did that but it still gives me the same error. I thought it had something to do with declaring CTileMap TileMap in main.cpp, and player.cpp not seeing it because it was declared after all the source files were included.

Share this post


Link to post
Share on other sites
Sorry, I was just talking about generally setting out the project.

In regards to your problem:

You could set TileMap as either a global variable in your master header, or as a member of the class you are using it within, depending on how you want to use it. I'm sure there will be other ways of doing it (extern?), perhaps somebody a bit more up on C++ could suggest others?

Share this post


Link to post
Share on other sites
May-be it cannot be seen because you have stripped much contents out of your headers, but if a header doesn't need to know about another class, it shouldn't include the respective header.

Otherwise you might learn about using forward declarations to break cyclic dependencies.

Share this post


Link to post
Share on other sites
Maybe my answer is in that link you gave me, I've read that before, but I don't think that's what I'm looking for. I'm not sure if I clearly stated my question.

Player.cpp can't find TileMap (an object of class CTileMap), which is declared in main.cpp. Where do I declare TileMap so that it can be seen by tilemap.cpp, player.cpp, and main.cpp?

Thanks again.

Share this post


Link to post
Share on other sites
Have you read this?

An alternative might be to pass the file map by const reference to the Collision method, or pass the Object instance to a TileMap member function that will report any collisions. This way you can avoid global variables, which is usually a very good idea.

Share this post


Link to post
Share on other sites
Master headers don't work that well. Been there, done that, then read this article.

It's worth knowing that you can get globals from other files using the extern keyword.

Declare a global normally in one file, for example, int numFoo = 0; and then in any other file that needs it, do this around the top:

extern int numFoo;


Notice I did not repeat the initial value. For global objects with constructors, only write the construction arguments with the 'normal' declaration, not in any of the extern declarations.

All warnings about globals apply, though. I'm only using this for my log.

Share this post


Link to post
Share on other sites
Interesting article.

I recognise the increase in build times and the rejigging of #include directives, but I've always used a master header as a nice guide to the code. Perhaps it's just the way my brain organises it, but the master header provides a quick and easy guide to the path through the project's code.

Like most programming practices I've come across, it seems like a trade off. Master headers increase build time, make you focus on the compiler's operation more (is this a bad thing though for beginners?) but decrease complexity in the code. Or have I missed the point completely? [grin]

Share this post


Link to post
Share on other sites
I don't see how #include "all_headers.h" could be called a guide, as it doesn't provide any useful information as to what uses what.

I haven't used master includes but they still wouldn't solve the issue of circular dependencies and the need for forward declarations? If that is so, I can't see why including all should be less complex than including only what you need. (Or do you also rely on the order of inclusion - now that would be complicated.)

Share this post


Link to post
Share on other sites
I always liked the idea of putting it all in one place. Encapsulation, right?

Actually, the biggest problem with master headers is circular dependencies. A lot of times, a class will need "all_headers.h" in it's header, and at the same time you want that class's header in "all_headers.h"! Not to mention, it puts headers in files that don't need them, further decreasing encapsulation.

I suppose it would work to put certain headers, like standard library headers, and a couple others that depend on nothing and that everything else depends on, maybe exception classes.

Share this post


Link to post
Share on other sites
Quote:
Original post by rip-off
Can you give me your definition of encapsulation? I don't think it matches mine... [smile]


Shoot, what'd I say???

Encapsulation refers roughly to the property of a module of being independent of other modules, and especially being independent of their guts. That's not a particularly well-worded definition, though. What's yours?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this