C++ – How to effectively use one file per class in C++

ccode-organizationproject-structure

Even though I have a decent bit of professional experience with object oriented programming in Java and a basic familiarity with C, I've run into a bit of a mental block with C++ that I was hoping other developers could help me shine a light on.

In Java, almost every time I define a class I naturally create a new .java file. Of course there are the exceptions of internal and anonymous classes, but by and large a new class means a new file. With new classes come packages to organize them and so on, and as I've started dabbling in C++ I've taken that same approach of one .java file per class and extended it to one .hpp file and one .cpp file per class. However, it seems that there are a lot of problems with this approach. The one that's been on my mind lately is like this:

Say I have some kind of game where there is a class representing the game world and a class to represent the units. If the game world class has a method to get the unit at a location, that's all well and good. However, if I want to have a method for retrieving the containing world from the unit, the include directives won't resolve in the way that I'm used to building projects since each header includes the other. I know that there of course has to be a clean solution, and I want to know if some more experienced developers may have ideas on resources about C++ project organization, or on handling the specific construct I mentioned.

Best Answer

In C++ you have full flexibility how you want to organize your files. But you have to get accustomed to this freedom to make the good choices:

  • A first practice is to have include guards in headers, in order to avoid that due to shared dependencies, the same header gets included multiple times.

  • A second is discipline: make headers self-sufficient and always include in them all the required header dependencies. Make no assumptions about what the including code should have included else. Do not worry about mutual dependency: this is usually handled through forward declarations and separating declaration from implementation

  • A third is to decide and use consistently what granularity you want for your headers: do you want a header per class (if you're used to it, why not continue) ? Or do you prefer a header for higher logical units (e.g. class and its auxiliaries) ?

  • Then come the question of directories and namespaces (perhaps something that comes closes to the notion of java "packages" for the moment): do you keep files of different namespaces in different directories or not ? Note that this reflection may also be loosely related to the question of whether making a library subproject or not.

  • Don't forget that you development environment could also influence the chosen directory structure (example or example).

For the future, it could be interesting to keep an eye on the concept of C++ modules. It's not yet standard, so you shouldn't build your current approach on it now. Yet it is interesting, as it intends to ease componentization of code using a java package like fashion, that would gradually get rid of headers. But it will still let you a big freedom for the file organisaton.

Related Topic