Multiple files and Object Oriented Programming - c++

In my application, I use multiple files, each file contains a class, is it a good idea to gather all C++ files (implementation of all classes) in one file and gather all headers in another file, or this is not good for some reason but code organizing ?

Keeping declarations and definitions organized in to separate but related translation units can help to decrease compilation times.
And don't disregard the value of keeping things organized for humans too! Software can consist of many thousand different objects, functions, and other parts. Keep it as simple as possible (but no simpler)!

If you keep declaration and definitions of a class in the corresponding files, they need only to be recompiled when you made changes in these class. Also changes in one class only requires relinking of the changed class against the classes which depend on it. Therefore it decreases compile time.
It makes it also much more easier to debug, as the compilation errors can be traced back to one file.
There is no advantage to concatenate all files in one, as far as I know

In C++ it really doesn't matter so much. In some languages, such as Java, the compiler requires that every class be in a separate file, but as long as you make sure that the different files reference each other there is no reason either way.

Perfectly agree with other answers, and I would like to add my piece :
Breaking into several files also make it easier when using an editor. You can then use several tabs. (Imagine if your browser displayed all your pages one after another in one window only !)
It is even acceptable to break a class implementation in several files if the implementation is big.
On the other hand, there are sometimes reasons to put several classes in one file, for example when those classes are small and/or very highly related. For example a FooObject and its FooAllocator, or a FooObject and its small FooSubObject used only by him.

Related

What is the purpose of using multiple .cpp files in one solution?

As I've learnt more C++ with time, I've looked for a use for multiple .cpp files in one solution. This has been to no avail.
From what I can tell, multiple .cpp files just add more complexities when it comes to making sure there are no duplicates of integers or whatever, and all the idea is used for is just to sort an application a bit better. Is that the only use of doing this?
As a beginner even I thought that multiple files made it difficult for me to understand the code. But after working on a few projects I realized the importance of this modularity approach.
There are many reasons for having multiple files in the project. Here I list some of them.
Let's say you are in company and you want to distribute task between many employees. Now if you as them to work on a single file then it will get difficult to keep track of who is editing what. So, we break down the task in smaller tasks where each task can be done by an individual. We provide him with a particular interface. In the case of C++, we can provide a header file with public methods and public variable. So now this individual knows what methods he can use from the part that his coworkers are working on.
So, in this situation, multiple files serve the following functions:
Divide and Conquer: Divide task between co-workers without running into the risk that they might break someone else's code.
Keep code modular, where each file/class has a specific function. So, that in future if we want to add or delete some features then we can just edit that class without tinkering too much with entire codebase.
Optimize compilation: Let's say you have 400 files in code and now you change 1 line in a certain file. Now you can individually compile the edited file. Wherelse if it was one giant file then it will waste time to compile things that are not changed.
About complexity, actually distributing code in different files reduce code complexity.
Consider that you are working on a solo project. Let's say it has some database, functionality, input-output, GUI, some calculations like searching, etc. Now consider if you include all this thing in 1 file then it will become difficult to keep track of various thing in no time as project size increases where fast without even creator realizing. This will lead to duplicate names of functions, variables, structures, etc. Now instead of having functions log in each file which logs the status of the database, input-output, etc of its respective file, you will have one file with databaseLog, inputLog, etc. And what's the guarantee that you will not have some other functionality in GUI for which inputLog will not be the suitable title.
Let's say you have some error or crashes in a project that it is easier to look at one file as there are fewer things to look at. While in one file you will have a difficult task in keeping track of what belongs to what functionality. So, Debugging gets simplified.
So, in short, you can say that if file names are assigned according to their purpose than multiple line code reduces code complexity rather than increasing it.
If you are trying to read someone else's code with multiple files then here are some tips,
Look at one file at a time and find what exactly it is doing. Most beginners do mistake that they start with main and keep on searching functions as they encounter.
I will recommend you to note down what each function do.
Use flowcharts.
And when you are working on the project make sure that each file has its own purpose, it is modular and functions do one thing. Make sure files are in a proper hierarchy according to their purpose. Also, it will be easier for you to try and implement these practices in future if use them daily. Good luck.
Hope it helps.

OOP - Do I over complicate things?

I was looking at some of my projects and comparing them to things I've seen on github and I feel like I over-think things. I like OOP but I feel like I make too many files, too many classes.
For example, on a small project I had of a game of checkers, I had so many files that could maybe all go into one file/class. How do I know when I have over-thought my solutions? Here is what some of my files look like;
|src
| |- player.cpp
| |- piece.cpp
| |- color.cpp
| |- ...
And of course, there are many more files that will deal with things like rules, setting the game, GUI, etc,. But in this short example you can see how my projects can and will get very large. Is this common, to write things in this way? Or should I simply write a player.cpp file that either contains multiple classes that, in this case, are related and would set pieces/colors/king information, etc,.
Yes, distributing your code to multiple files is a good practice, since it makes your project maintainable.
I can see your concerns on a small project (is the overhead worth it?), but in real big projects, if you don't do it that way, you will end up with people scrolling forever in a large file, and using searching trough the file to find out what they are looking for.
Try to keep your files compact, and one class per file, where every class is robust and its goal is clear.
Sometimes, we write functions to files. It would not be wise to have a file for every small, inline function, it will increase the number of files without a reason. It would be better to have a family of functions inside a file (functions related to printing for example).
At the end, it's probably opinion based which is the ideal balance between size and number of files, but I hope I made myself clear.
You are actually asking two distinct questions: "what is the good granularity for separating functionality into classes" and "what is the good practice to organize project file structure". Both are rather broad.
The answer to first one would probably be to follow a single responsibility idiom. The answer to second one would be to make folder structure resemble the namespace structure (like in boost for example). Your current approach with storing everything in src folder is not good for C++ because it will lead to longer file names to prevent names collision when classes with the same name appearing in different namespaces. Larger projects indeed tend to have too many files as one class would require 4-5 files. And that leads to yet another question of selecting appropriate granularity for projects...
People tend to worry a lot about "too many classes" or "too many files", but that's largely a historical carryover. 40 years ago when we wrote programs on punch cards, and had to carry large trays and boxes of them (and not drop them!), this certainly would have been a concern. 35 years ago when the biggest hard drive you could get for a PC was 33MB, this was a concern. Today, when you wouldn't consider buying a PC with less than 512GB of SSD, and have access to terabytes and petabytes of online storage, the number of files and number of bytes taken up by the programs are essentially immaterial to the development process.
What that means to us humans is that we should use this abundance of capacity to improve other aspects of our code. If more files helps you understand the code better, use more files. If longer file names help you understand the code better, use longer file names. If following a rule like "one .cpp and one .h file per class" helps people maintain the codebase, then follow the rule. The key is to focus on truly important issues, such as "what makes this code more maintainable, more readable, more understandable to me and my team?"
Another way to approach this is to ask if the "number of files" is a useful metric for determining if code is maintainable? While a number that is obviously too low for the app would be concerning, I wouldn't be able to tell you if 10 or 100 or 1000 was an appropriate number (at least without knowing the number of classes they contain.) Therefore, it doesn't appear to be a useful metric.
Does that mean a program should have 1000 files all piled into a single folder, all compiling and linking into a single library or executable file? It depends, but it seems that 1000 classes in the same namespace would be a bit crowded and the resultant program might be too monolithic. At some point you'll probably want to refactor the architecture into smaller, more cohesive packages, each with an appropriate area of responsibility. Of course, nobody can tell you what that magic number is, as it's completely application dependent. But it's not the number of files that drives a decision like this, it's that the files should be related to each other logically or architecturally.
Each class should be designed and programmed to accomplish one, and only one, thing
Because each class is designed to have only a single responsibility, many classes are used to build an entire application

Putting method implementations of the same class in different object files

I'm working on a big project in C++.
I have many classes which have methods that do completely different things (like one dumps, another modifies the object, another checks it to see if it's valid and so on...).
Is it a good style to put the implementation of a method for all the classes in a source file (or in a group of object files that may be archived) and all of the implementations of another method of the classes in another archive?
Could this be good when linking, maybe when someone doesn't need the dumping methods (for example), or it's better to keep the method implementations of the same class in the same source file, in order to not make confusion?
There are trade-offs.
When you change the implementation of any function, the entire translation unit must be re-compiled into a new object file.
If you write only a single function per translation unit, you minimize the length of compilation time caused by unnecessary rebuilds.
On the other hand, writing a single function per translation unit, you maximize the length of compilation time from scratch, because it's slower to compile many small TU's than a few bit TU's.
The optimal solution is personal preference, but usually somewhere in between "single function per TU" and "one massive TU for entire program" (rather than exactly one of those). For member functions, one TU per class is a popular heuristic, but not necessarily always the best choice.
Another consideration is optimisation. Calls to non-inline functions can be expanded inline, but only within the same translation unit. Therefore, it is easier for the compiler to optimize a single massive TU.
Of course, you can choose to define the functions inline, in the header file, but that causes a re-building problem, because if any of the inline functions change, then all who include the header must re-build. This is worse problem than simply having bigger TUs but not as bad as having one massive TU.
So, defining related non-inline functions within the same TU allows the compiler to decide on optimization within that TU, while preventing a re-build cascade. This is advantageous if those related functions would benefit from inline expansion and call each other a lot.
This advantage is mitigated by whole program optimisation.
Third consideration is organisation. It may be likely, that a programmer who looks at member function of a class would also be interested in other member functions of that class. Having them in the same source file will allow them to spend less time on searching the correct file.
The organizational advantage of grouping all class functions into a common source file is somewhat mitigated by modern IDEs that allow for quickly jumping from source file to header and from there to the other function.
Fourth consideration is the performance of the editor. Parsing a file of tens of thousands of lines or more can be slow and may use a lot of memory depending on parsing technique. One massive TU doesn't necessarily cause this, because you can use separate files that are only included together.
On the other hand, massive number of files can be problematic for some file browsers (probably not much these days) and also for version control systems.
Finally, my opinion: I think that one source file per class is a decent heuristic. But it should not be followed religiously when it's not appropriate.
Some organizations have rules that mandate one definition per unit. In these organizations, a header file can define only one class, and a translation unit can define only one function. Other organizations mandate at most one source file for each header files (some header files have no implementation).
The optimal thing to do is somewhere in between. I generally don't care about compiler or linker performance. I do care a lot about code readability and maintainability. A source file that implements some class that is thousands of lines long is hard to navigate. It's better to break that file into multiple files. Breaking it into hundreds of files, one file per function, makes for a directory structure that is difficult to navigate. Breaking it into chunks of closely related functions keeps the directory structure and the contents of each file navigable.
However, and this is a big however: Why is your class so large that you have to worry about this? A class whose implementation spans thousands of lines or dozens of files is a code smell.

Organizing large C++ project

Should all C++ code in a project be encapsulated into a single class with main simply calling that class? Or should the main function declare variables and classes.
If you are going to build a large project in C++, you should at the very least read Large Scale C++ Software Design by John Lakos about it. It's a little old but it sounds like you could benefit from the fundamentals in it.
Keep in mind that building a large scale system in any language is a challenge and requires skill and discipline to prevent it falling to pieces very quickly. Don't take it lightly.
That said, if your definition of "large" is different than mine then I may have alternative advice to give you. I'm assuming you're talking about a project where the word "million" will be mentioned in sentences that also contain the words "lines of code".
for large C++ projects, you should create many classes!
main should just kick things off (maybe doing a few housekeeping things) and then calling into a class that will fire up the rest of the system
If it's a class that really makes sense, sure -- but at least IME, that's a fairly rare exception, not the general rule.
Here, I'm presuming that you don't really mean all the code is in one class, but that there's a single top-level class, so essentially all main does is instantiate and use it. That class, in turn, will presumably instantiate and use other subordinate classes.
If you really mean "should all the code being contained in a single class?", then the answer is almost certainly a resounding "no", except for truly minuscule projects. Much of the design of classes in C++ (and most other OO languages) is completely pointless if all the code is in one class.
If you can put your entire project in one class without going insane, your definition of "large" may be different than most people's here. Which is fine -- just keep in mind when you ask people about a "large" c++ project, they will assume you're talking about something that takes multiple person-years to create.
That said, the same principles of encapsulation apply no matter what the size of the project. Break your logic and data into units that make sense and are not too tied together and then organize your class(es) around those divisions. Don't be afraid to try one organization and then refactor it into another organization if you find yourself copy-pasting code, or if you find one class depending too heavily on another. (Or if you find yourself with too many classes and you're creating many objects to accomplish one task where a single object would be cleaner and easier on you.)
Have fun and don't be afraid to experiment a little.
In C++ you should avoid putting entire project in one class, irrespective of big or small. At the max you can try putting it in 1 or 2 namespace (which can be split across the files).
The advantage of having multiple classes are,
Better maintainability of your code
Putting classes in multiple .h and .cpp files (i.e. small modules) help you fast debugging
If all code is in one class and changes are made somewhere then one has to compile whole project. Instead, if project is across modules, one can just compile the module where changes are made. It saves time a lot.
No! Each header/implementation file pair should represent a single class. Placing a large project in one file is a surefire way to disaster: the project become unmaintainable and compiling will take ages. Break up your code in to appropriately sized pieces.
The main function should not declare the classes, rather, the file it contains (often named something like main.cpp, driver.cpp, projectname.cpp) should use #include directives to make the compiler read the declarations in header files. Read up on C++'s separate compilation model for more info.
Some newcomers to C++ find the compilation model - as well as error codes generated when you screw it up - incomprehensible or intimidating and give up thinking it's not worth it. Don't let this be you. Learn how to properly organize your code.

File/folder layout for a large C++ project with multiple levels of inheritance

I'm in the planning stage of a relatively large (10k+ lines) project with several classes (30+) and several levels of class inheritance (5+).
What is the best (or most conventional) way to lay out my project in terms of file and folder structure?
Should I have one file per class? Should I have one folder per inheritance branch?
Should I have an 'include' folder that contains my header files, or should my header files be in the same folder as my .cpp/.c files?
I plan on regularly adding more classes (adding more levels to the inheritance tree). At the lowest level in the tree, implementations are likely to be relatively unrelated but still override the same virtual functions. Should such unrelated implementations reside in the same folder?
Thanks,
Advait
1) Yes. One file per class in most cases is a good idea. Unless you have a really trivial class, or a collection of abstract interfaces, use one class per file.
2) Try to separate things. Usually in a project that big, you'll have some code that are specific to some parts, others that are common to many parts. Those that are very limited in usage, just keep it 'locally'. Others, put is in include dirs.
3) No need really. It is usually better to keep classes (i.e. files) which are closely related, close together; I'd try to keep them together, unless you have something like a generic interface, in your global includes, and specific inheritance inside a module dir.
1) This looks more like Java type - but if your classes don't take more than 4 lines, mayn't be a good idea. But if later on you want to extend an already existing class, one file for each class is a good idea.
2) That's a choice for you, how to arrange you .h files and .cpp files. But if lot of dependencies are to be for a single class, it seems reasonable to put related ones in one place.
3) Maybe. But put your base classes/interfaces at a central part and derive around it.
Should I have one file per class? Should I have one folder per inheritance branch?
Thanks to code indexers I often forget how and where the code is actually on disk.
File per class to me makes no sense. Especially in C++ I tend to have lots of small utility classes.
Generally: component is a directory. All components live under the same root. (This is more of an unfortunate consequence that I have to use make as a build chain. With better build systems like SCons which support recursion natively it doesn't really matter.)
I stick to the general principles of reusability, sufficiency and cohesion (as per Booch) for grouping classes. It happens often that I put the code into a shared/static library to facilitate integration into the build chain, thus for the grouping of classes into components/directories I use principles very similar to the ones used for grouping methods in the classes.
Should I have an 'include' folder that contains my header files, or should my header files be in the same folder as my .cpp/.c files?
I personally prefer headers in the same directory with source files.
Notable exception are the public headers which define the public interface of the component. Those I put into the include/compname/ sudbirectory: then it is easy to see that the change I'm doing/about to check-in is going to have impact on other components.
Obviously other components are allowed to include only the headers from the $ROOT/compname/include/compname/ subdirectory. (Having compname/ dir under include/ makes include directives in other files to look like #include "compname/headername.h" what helps readability and also prevents header name collisions.)
I plan on regularly adding more classes (adding more levels to the inheritance tree). At the lowest level in the tree, implementations are likely to be relatively unrelated but still override the same virtual functions. Should such unrelated implementations reside in the same folder?
Inheritance is rarely relevant to the physical layout of files.
Base classes are modified seldom since they have little impact on the business logic. Top level classes is where the meat of the logic is and it is going to be worked on by many people for a long time. Thus the basic classes, reused by many components, deserve to have their own component. Simply to move them out of sight.
That brings another important point. How many people are going to work on the project? On one man project you can do pretty much whatever you want the way you want. On a team with 3+ people, the component/module would serve as a natural container for one person to work independently on it. Thus the form project takes may not depend on how classes hierarchy looks - rather the places of code which are going to be worked on most should be sufficiently isolated from each other. And class hierarchy if needed should accommodate for that: you should avoid cases when one person works on a base class - another on its descendant. That is the case where aggregation may be considered instead of inheritance.
The idea is simple. Imagine that you are drawing a dependency graph between you classes and choose a layout that minimize dependencies between files.
This is true at file level, and this is also true at folder level but for larger code units.
You should also be aware that compiler's doesn't optimize code well between files (problem is linker). So if you have tightly coupled classes, keeping them in the same file is good for performance. Another solution when it is possible it to make them headers only classes.
Where to keep headers ? If you are providing a library you will have to put them in usual system directories. But as C++ headers contains code, for other cases keeping them with cpp files is usually the best solution. It makes editing both hpp and cpp at once simpler.