Hi there
I have been building a program separately and testing the code in sections. Which is fine as it works individually. However two of the classes are designed to share variables. The idea is the first class generates a partcile and then scans through a list of gridCells. It then either creates gridcell and updates itself, or updates itself and then the gridcell if one already exists.

I think the error comes from the compiler not knowing which to compile first and so doesn't compile as one of the classes can't access the other that hasn't been compiled yet.

Is there a way to specify which one it should compile first? Or do I need some kind of middle class that would first compile the particle and then the grid second, allowing them to then access each other as they would have then both compiled individually?

Many thanks

Thanks I had #pragma once but changed it to the solution you said. The problem still persist as a header includes itself. Which annoyingly does make sense.

I have

#include <windows.h>		// Header File For Windows
#include <gl\gl.h>			// Header File For The OpenGL32 Library
#include <gl\glu.h>	
#include "MACgrid.h"
#include "Conversion.h"

in one file and then

#include <windows.h>		// Header File For Windows
#include <gl\gl.h>			// Header File For The OpenGL32 Library
#include <gl\glu.h>	
#include "console.h"
#include "Particle.h"

In the other file as Particle include MacGrid.h and MacGrid.h calls particle it then calls itself. Is there anyway to prevent this? Or do I need to do some rethinking of the structure. Annoyingly this was an oversight on my behalf as I was testing all the results in a console before merging the files.

Thanks

This is actually pretty common. There are two solutions:

  • Good: figure out what part is needed by both Particle and Grid and put that into a third header. Now each can #include that third header and there's no cycle
  • Less Good: Merge the two headers into one. There's no cycle now, but also the code has become much more tightly coupled (a bad thing)

By the way: #pragma once and the more traditional header stop code have effectively the same semantics. The #pragma once style can be just a little more efficient than the older style: With the old style, the compiler has to read the whole header looking for the #endif but can just stop after seeing #pragma once edit: P.S. Sometimes, the best you can do is to treat one of the types as a void* or if you can, a BaseType* in the other type.

Edited 5 Years Ago by griswolf: n/a

This is called a circular referencing problem (Particle needs MapGrid, which needs Particle, which needs MapGrid, ... ad infinitum). Headers guards won't solve that problem. You need to either break the circular referencing through a (better) design of the software, or you can turn the circular referencing to a semi-circular referencing.

Options to restructure:
- Perhaps the functionality for which one of the classes needs the other could be implemented differently. Often, circular dependencies are an indication that the tasks are not properly split between the two classes. Take a second look at the functionality to see if it really makes the most sense to do it that way.
- Perhaps you simply need to define a base class for one of the two classes. If one of the classes uses the other in a simple non-intrusive manner, then, probably, you can put this simple interfaces as pure virtual functions of a base class. In this case, you have no more circular referencing. For example, MapGrid could depend on BaseParticle, and Particle could depend on both MapGrid and BaseParticle, i.e. no more circular dependency.

Breaking Circularity:
If the above options are not suitable for your application, you can break circular dependency via forward-declarations. Here is an example:

//in MapGrid.h
#include <windows.h>
//...
//do not include Particle.h

class Particle; //forward-declaration of class Particle (found in Particle.h)

class MapGrid {
  ///... uses Particle* or Particle& in the function prototypes or data members.
};

//in MapGrid.cpp
#include "MapGrid.h"
#include "Particle.h"

///... here, the member functions of MapGrid class can be implemented using the Particle class (since it is now defined by the inclusion of Particle.h).

You can do the same for Particle.h, although only one of the two header files would have to resort to this mechanism to break the circular dependency of the header files.

You might wonder why I did show this forward-declaration trick before mentioning the design restructuring. The reason is because you should first consider rethinking your structure, and only after, should you consider this work-around.

Awesome thanks a lot for the fast replies. Upon looking further at my problem I can get rid of the grids from the particles. Originally I was having a particle generate then check through the grids to see if it is inside one. If it wasn't it would generate a new grid. Now I have the grid take a partcile with its position, then check through the grids itself and generate a new instance of itself. This is less work for the computer and is the same from what I can tell. Just needed to rethink of doing it as a computer as opposed to me doing stuff on paper.

Why should I only do the forward-declarations as a last resort?
Is there a particular thing it does that makes the program slow/unstable?

Many thanks again hopefully sorted it out now

>>Is there a particular thing it does that makes the program slow/unstable?
No. It makes absolutely no difference in terms of performance, it is just a trick to get the compiler to do its job.

>>Why should I only do the forward-declarations as a last resort?
I wouldn't call forward-declarations a last resort (there are far worst things, like using a void* and doing casts later). There is nothing wrong with a forward-declaration, but it should be considered only after taking a close look at the design to see if it is necessary. The reason is simple. A forward-declaration is generally used to achieve inter-dependency between two classes, which is never desirable on a software design and maintainability stand-point, but it is not always avoidable. But if the inter-dependence can be avoid, it will lead to better design. You have experienced that yourself. You looked back at your design a found a better, less-coupled way of achieving the same task (with a bonus of efficiency). That's why I recommended rethinking your design first, because I was quite certain that you could find a solution that didn't involve this inter-dependency (most of the time, forward-declarations are avoidable via better design).

Edited 5 Years Ago by mike_2000_17: n/a

Comments
Good points
This question has already been answered. Start a new discussion instead.