Arranging Declarations and Definitions
The order in which you declare or define classes and functions has to obey the fundamental rule:
The compiler has to have seen a declaration or a definition of a variable, class, or function before you try to use it.
That is, if you use a variable in an expression, the compiler has to have seen a declaration or definition of it, such as int i; If you call a function, the compiler must have seen at least a declaration (function prototype) of the function already, if not the entire function code (the definition). If you declare a variable to be of some class type, like Cart_vector, the compiler must have seen the class declaration (e.g class Cart_vector {blah blah}; ) already.
If you break this rule, the compiler will give you either an "unknown identifier" sort of error, or depending on your IDE, might think you are trying to use something that it saw in a default header file.
Declaring a function with a prototype means that you can then put the code for that function (the "definition") anywhere you want. The prototype tells the compiler everything it needs to know in order to compile your calls to that function.
Once you keep the compiler happy, the second consideration has to do with readability to humans such as yourself or other programmers. This is a matter of taste and style.
Real programmers put declarations of classes and functions in separate header files, and then the function code in separate source files, a header and source file for each class or group of related classes. This breaks the code up into easy to re-use independent pieces that are also small and easier to read.
But if you are stuck with putting everything into one source file, follow these rules.
The best place to put member functions that you define outside the class, and non-member functions that are closely related to a class, is just after the class declaration, so that the reader can tell that these go together. Don't make the reader rummage through the code in search of all the pieces of a class.
Put the classes in a "building-block" order for the compiler, and a meaningful order for the humans. For example, suppose the Gold_Mine class uses the Cart_point class, and the Miner uses the Gold_Mine and Town_Hall classes. A point is conceptually simpler for humans than a vector, so Cart_Point should appear before Cart_Vector.
Finally, the functions that are called by main make up a traditional function hierarchy, and so should appear in our standard "top-down" reading order for human benefit.
-----------
struct Cart_point
{
blah blah
};
double Cart_distance(Cart_point p1, Cart_point p2)
{
blah blah
}
struct Cart_vector
{
};
functions closely related to Cart_vector class
class Gold_Mine
{
};
class Town_Hall
{
};
class Miner
{
};
Miner member functions defined outside the class
bool Miner::update()
{
}
prototypes for functions called by main
int main ()
{
}
functions called by main
-----------
Most people would consider it silly to put prototypes in for functions like Cart_distance given that the definition is going to appear right away. Notice that you can't declare Cart_distance until the compiler has seen Cart_point! So the only place the prototype could be placed is just before the definition anyway!
If your compiler warns about the missing prototype,
either ignore or turn off the warning.