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

I am at the planning stage of a relatively large project (10k + lines) with several classes (30+) and several levels of class inheritance (5 +).

What is the best (or most common) way to lay out my project in terms of file and folder structure?

  • Should I have one file for each class? Should I have one folder for each inheritance branch?
  • Should I have an include folder containing my header files, or should my header files be in the same folder as the .cpp / .c files?
  • I plan to regularly add additional 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 be in the same folder?

Thanks,
Advait

+4
source share
4 answers

1) Yes. In most cases, one file for each class is a good idea. If you do not have a truly trivial class or set of abstract interfaces, use one class for each file.

2) Try to separate things. Usually in a project that is large, you will have some code specific to some parts, others that are common to many parts. Those that are very limited in use, just keep it "local". Others on the list include dirs.

3) Actually no need. It is usually better to keep classes (i.e. Files) that are closely related to each other; I would try to bring them together if you do not have something like a common interface, in your global inclusion and specific inheritance inside the module.

+5
source

1) This is more like a Java type, but if your classes do not occupy more than 4 lines, this may not be a good idea. But if you later want to extend an existing class, one file for each class is a good idea.

2) This is the choice for you how to organize .h and .cpp files. But if a lot of dependencies should be for one class, it seems reasonable to put related ones in one place.

3) Maybe. But put your base classes / interfaces in the center and create around it.

+1
source
  • Should I have one file for each class? Should I have one folder for each inheritance branch?

Thanks to code indexers, I often forget how and where the code is actually located on disk.

The file for the class does not make sense to me. Especially in C ++, I tend to have many small utility classes.

Typically: a component is a directory. All components live under one root. (This is more likely an unfortunate consequence of the fact that I have to use make as a build chain. With more advanced build systems like SCons that support recursion, this doesn't really matter much at first.)

I adhere to the general principles of reuse, sufficiency and cohesion (according to Booch ) for grouping classes. It often happens that I put code in a shared / static library to facilitate integration into the assembly chain, so I use principles very similar to grouping classes into components / directories that are used to group methods into classes.

  • Should I have an include folder containing my header files, or should my header files be in the same folder as the .cpp / .c files?

I personally prefer the headers in the same directory with the source files.

A notable exception is public headers, which define the public interface of a component. The ones I put in include / compname / sudbirectory: then it's easy to see that the change I'm making / about to register will have an effect on other components.

Obviously, other components are allowed to include only the headers from the $ ROOT / compname / include / compname / subdirectory. (With compname / dir in include / make, include directives in other files to look like #include "compname/headername.h" , which helps readability and also prevents header name conflicts.)

  • I plan to regularly add additional 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 be in the same folder?

Inheritance rarely refers to the physical location of files.

Base classes rarely change because they have little effect on business logic. Top-level classes are where the meat of logic is, and many of them will be processed for a long time. Thus, core classes reused by many components deserve to have their own component. Just move them out of sight.

This is another important point. How many people are going to work on the project? In a single-person project, you can do almost anything you want, as you want. In a team of 3 people, the component / module will serve as a natural container so that one person can independently work on it. Thus, the design of the form may not depend on what the class hierarchy looks like - rather, the places of the code that will be processed on the majority should be sufficiently isolated from each other. And the class hierarchy, if necessary, should take this into account: you should avoid cases when one person works in a base class - another on his descendant. This is the case when, instead of inheritance, aggregation can be considered.

+1
source

The idea is simple. Imagine drawing a dependency graph between your classes and choosing a layout that minimizes dependencies between files.

This is true at the file level, and this is also true at the folder level, but for larger blocks of code.

You should also know that the compiler does not optimize code between files (the problem is the linker). Therefore, if you have closely related classes, storing them in a single file is useful for performance. Another solution, when possible, is to make them the headers of only classes.

Where to store headers? If you provide a library, you will have to put them in regular system directories. But since C ++ headers contain code, for other cases saving them with cpp files is usually the best solution. This makes editing both hpp and cpp easier.

0
source

Source: https://habr.com/ru/post/1315986/


All Articles