   Structure of a large scale c++ program
  I never really grasped the idea of making your own headers in C++, and why I couldn't/shouldn't put all of my code in one big cpp file. Could someone run me through the basics of subdividing your program into files?*TO AVOID HAVING TO READ THROUGH EVERY POST*:The last couple posts on this page are where I've worked my problem down to, so if you don't mind please comment on those posts. Thanks.[Edited by - saeedm on January 30, 2008 10:22:54 PM]
Article on GDNet on this subject.   ;Quote:Original post by saeedmwhy I couldn't/shouldn't put all of my code in one big cpp fileIt's a nightmare to read, keep track of, or organise. Do you want to read through a single code file, potentially tens or hundreds of thousands (or, in very large scale programs, millions) of lines in length?Also, headers go some way towards separate interface from implementation. If you provide headers, then other developers can use your library (say) without having to have the entire source to that library.   ;  "I never really grasped the idea of putting things in file folders, and why I couldn't/shouldn't leave all my papers lying around on my desk." :/   ;Quote:Original post by Zahlman"I never really grasped the idea of putting things in file folders, and why I couldn't/shouldn't leave all my papers lying around on my desk." :/Not lying on the desk, but all on ONE really big sheet of paper.Each class gets it's own file.Each concept of code gets its own folder.  When a concept needs to be broken down, those sub-concepts get their own folder.Most files are around 200-500 lines.Examples:game/debug/... {logging and such}game/debug/cpuprofiler/... {Lots of good debugging info}game/system/memory/...  {memory management related stuff}game/minigames/core/collision/... game/rendering/scene/transition/...   ;  This is driving me nuts...its seems like something so simple, yet I run into tough decisions about it multiple times throughout my coding, and I'm sick of it! Could you guys take a look at just one of the things thats on my mind...I'll take you through my reasoning, and hopefully with that you can see what I'm trying to do - and show me how to do it right! My perfect file structure for main.h/cpp would look something like this:/* main.h */#includes - 'external' ones, like <iostream>global vars/* main.cpp */classes/functions - split these into multiple filesmain()This way every #include and every global var is accessible from any function/class below it (all of them). However, this can lead to cyclic dependencies in the classes/functions section. So, in main.h I keep the interface of each function/class/structure./* main.h v2 */#includesglobal varsfunction/class/struct declarations - ALL of them*Now it should work (right?). Now, back to that comment - 'split these into multiple files' - OK, so network stuff goes in a file called network, graphics in a file called graphics, etc. In main.cpp, I simply #include network, #include graphics, etc. Doesn't matter the order - all functions are declared in main.h. I don't have to worry about including a single thing more than that - every variable, every external header, and every class/structure in my code is accessible by all of these new files: network, graphics,...*note: I noticed the makers of quake2 did a similar thing in their source. In one file, named g_local.h, they declared functions/vars/structs from various .c files. Looks something like this:// g_cmds.cvoid Cmd_Help_f (edict_t *ent);...// g_items.cvoid PrecacheItem (gitem_t *it);...// g_monster.cvoid monster_fire_bullet (edict_t *self, vec3_t start, vec3_t dir, int damage, int kick, int hspread, int vspread, int flashtype);...But thats where the similarities end...Thanks for following through this far - hopefully you see my intentions. If I were to store the interface for each section of code (network, graphics...) in its own header file (network.h, graphics.h..), if I ever wanted to access even a single var from graphics, I'd have to #include its header. That leads to lots of  repetitive includes, and headaches, and brings back cyclic dependencies. Yet, its the generally accepted way of organizing files...so is there some technique to make the good way easier?[Edited by - saeedm on January 17, 2008 2:44:50 AM];  I don't think I made my last post clear enough...I'm sort of arguing against that article (1st post), at least for personal coding purposes.typical file structure:*file*.h for declarations, *file*.cpp for implementations, and #include what you need when you need ita more unified yet still organized way:(doesn't really matter if the graphics, sound, mouse are .h or .cpp)/* graphics.h */varsfuncs - (implementations)/* sound.h */varsfuncs - (implementations)/* mouse.h */varsfuncs - (implementations)/* declarations.h */graphics declerations - vars & funcssound declarations - vars & funcsmouse declarations - vars & funcs/* main.cpp */#include declarations.h#include graphics.h#include sound.h#include mouse.huse graphics, sound, mouse funcs/vars here!main()return 0   ;  Compile times. In a recent project, there was a 500-line file named parser.cpp which contained a Boost.Spirit description of an NVIDIA PTX parser. That file alone took one full minute to compile with a recent high-end computer. Since I only ever changed that file once every two weeks, the one-minute compile time only happened once every two weeks as well, and the rest of the project compiled and linked in under five seconds. Had I included that file's contents into a single main translation unite, I would have had to wait for the full minute compile time every single time I would have changed anything in the program. This would have been simply unacceptable.   ;Quote:#includesglobal varsfunction/class/struct declarations - ALL of them*First of all, you should avoid global variables.  Avoid "master include" files as well.Quote:Now it should work (right?).That's not the goal.  It is not about making it work, it is about logical organization that promotes maintainable code.  Crappy code and crappy organization will still "work", you just don't want to be the poor sap that has to go back and make any changes or fix any bugs.Quote:Now, back to that comment - 'split these into multiple files' - OK, so network stuff goes in a file called network, graphics in a file called graphics, etc. In main.cpp, I simply #include network, #include graphics, etc. Doesn't matter the order - all functions are declared in main.h. I don't have to worry about including a single thing more than that - every variable, every external header, and every class/structure in my code is accessible by all of these new files: network, graphics,...Think about why you need this level of accessibility.  Why break up your code into sub systems if you are just going to undo that by making everything accessible to everything else?Quote:Thanks for following through this far - hopefully you see my intentions. If I were to store the interface for each section of code (network, graphics...) in its own header file (network.h, graphics.h..), if I ever wanted to access even a single var from graphics, I'd have to #include its header. That leads to lots of repetitive includes, and headaches, and brings back cyclic dependencies. Yet, its the generally accepted way of organizing files...so is there some technique to make the good way easier?If your network code needs access to your graphics code, then your design is well and truly borked.  Your sub systems should be self contained.  There is no reason for graphics, sound, network, AI, etc to know anything about each other.   ;  Thanks for all the responses. Now I've got some real reasons to use the standard header method...before I thought it was just 'something you do'.   