C++ "proper" include file structure

Red Squirrel

No Lifer
May 24, 2003
68,458
12,611
126
www.anyf.ca
What is considered the universal proper way to organized files in C++? This is currently how I do it:

Function/class declarations in .h files, one .h per class/function, though occasionally I may have a "functions.h" file with small generic functions. I tend to organize it into folders as well.

Then the actual code goes into the .cpp file. In the .h I also include ifndefs to ensure if the header file is included more than once it will just get included once. Each header file includes any other headers that may be needed.

Then I have two main header files, includes.h and sources.h, and I have a little app that just auto generates a list of .h files in includes.h and a list of .cpp files in sources.h.

These two files are then included in the main program after including anything else.

I feel that this is probably not the right way. Is there a better way of doing it? It works, but it does rely on that custom app I wrote, or having to do it all manually.

I was also reading something where the .h file is actually included in the .cpp file of the respective class/function. How would that work as far as including it in your main program? I don't imagine you would include the .cpp files directly would you?

I know this is mostly just a schematics thing, but I want to move towards doing things a more proper way.
 

postmortemIA

Diamond Member
Jul 11, 2006
7,721
40
91
I'm fan of using forward declaration
Code:
Class A;
instead of
Code:
#include "class_a.h"
in headers, and then use the actual include in c++ modules, but only if necessary. This produces cleaner interfaces with less dependencies, and faster compile times. Also helps analyzing code manually or automatically. I don't do include everything into everything , that beats the purpose of the includes.
 
Last edited:

Red Squirrel

No Lifer
May 24, 2003
68,458
12,611
126
www.anyf.ca
Well I would be using forward declaration too where it is needed. I'm talking more about how to structure it so that when you compile the main program all the files needed are also included. Ex: having a master include file that includes all the .h and .cpp files etc.
 

Cogman

Lifer
Sep 19, 2000
10,283
134
106
Let me preface by saying I'm not a professional C++ developer.

I think the recommended setup isn't to have one giant "app" header but rather have every cpp file call out each individual header it needs. This can avoid problems where you end up with a polluted namespace that collides with implementations in weird and horrible ways.
 

Crusty

Lifer
Sep 30, 2001
12,684
2
81
You should be building every .cpp file into their respective object files, then linking said object files to produce your various exes and libraries. It doesn't matter(functionally) how or where you include your .h files so long as you can build .o files from your .cpp files. When you link your executables you just need to make sure to also link your .o files.

I've ever seen a C++ project where the output was a single exe or a single library. There are usually many exes and one-to-several library files being built.

Unless you plan on statically linking just about everything into all of your output files(huge waste of disk space and time), having one 'master include' file is just a giant hack to get around the lack of a proper build system and you'll never get to benefit from incremental building.
 

uclabachelor

Senior member
Nov 9, 2009
448
0
71
I don't usually code in C/C++ but when I do work on projects that require C/C++, the project files get separated into classes and/or functionality and their respective directories.

Files that use those instances would simply include the required header files..

In other languages, you would do the same with the files and directorys, but reference the namespace instead, which is similar to doing "#include".
 

Merad

Platinum Member
May 31, 2010
2,586
19
81
Well I would be using forward declaration too where it is needed. I'm talking more about how to structure it so that when you compile the main program all the files needed are also included. Ex: having a master include file that includes all the .h and .cpp files etc.

It sounds like you might have some confusion about how compilation works (or is supposed to work).

Your makefile/IDE/build system is responsible for making sure that all of the .cpp files necessary for the current build target are compiled, and linking the resulting object files together with any libraries to form the final library or executable output. You should never ever be #including .cpp files

Each .cpp should include all of the header files necessary for it to compile. Dependencies should be explicit as much as possible - for example if we use std::string, explicitly #include <string>, don't leave it out just because that .cpp file includes foo.h which happens to include <string>.

Each header file should include all the dependencies necessary for *it* to compile - through forward declarations whenever possible, through #includes when necessary. Header files should only contain code when absolutely necessary (e.g. template classes/functions). If your compiler (linker, technically) doesn't support link-time optimization you may need to inline some functions in headers.

Having said all of that, it's very common IME to have something like a "common.h" or "project.h" that has includes for the super-common headers that are used almost everywhere. Having it include all of your headers, however, is just lazy, and will cause Great Pain and Suffering™ when you start working on projects of significant size and/or with multiple developers. The exception is third party libraries - most will include a single "libraryname.h" that includes all of their stuff, because it's easier to just include it and move on rather than trying to figure out which of the two dozen headers in the library you need to include for each translation unit.
 

Red Squirrel

No Lifer
May 24, 2003
68,458
12,611
126
www.anyf.ca
I read about compiling everything into separate object files, but that seems a little excessive. I want to be able to just run a single g++ command to compile the whole program into one binary. I might look into splitting stuff up into separate object files when dealing with larger programs, but that's another topic. I don't actually want to make each and every class a separate object file.

I understand about trying to make classes as independent as possible, that's what I'm working on moving towards as right now it's kinda all a mess. I have my own "library" which is a series of included files that have base class/functions to deal with repetitious stuff like tcp/ip server/client class etc but I want to rewrite it in a proper format so that each section is more or less independent of each other and only includes what's needed, instead of including them all in a master file. I might even make it into a real library, though I personally hate dealing with those as they make the app less portable as it requires it to be installed in the system and each system is different such as where it puts the files.

The format I am looking at moving towards, and which I think is the proper way is this:

file: MyClass.cpp: (a class specific to the program)
Actual code for MyClass. MyClass.h is included on top

file: MyClass.h
The implementation of the class, along with "include guards" as other classes may include it too.

file: Main.cpp
All core includes added like iostream etc, and then my custom includes... but including each .cpp file seems like it's probably not the right way and if I include just the .h well the .cpp file is never seen. This is the part I'm hung up on.

I know it will work if I include the .cpp files which is what I've been doing but I know that's not the right way.

I eventually want to look into make and all that but it looks pretty complicated, so it's something for later. I suppose if i want to distribute anything I should look into it though to follow the normal way of doing ./configure etc... For now I usually just have a ./setup script that runs g++, moves files to proper locations, generates base config files etc and walks the user through any other steps.
 
Last edited:

Crusty

Lifer
Sep 30, 2001
12,684
2
81
Because you need to compile your independent CPP files into object files and link them to your executable.

Also, include guards are old now... look at #pragma once instead
 

Merad

Platinum Member
May 31, 2010
2,586
19
81
Yeahhhhh.... Separate compilation isn't "excessive", it's how C and C++ compilation is designed to work. It's rather silly worry about the structure of your include files when you're using such a derpy build process. You're setting yourself up for subtle build or even runtime errors that will be a bitch to diagnose, and you also have an environment where 100% standards compliant code will not compile correctly. It's time to step back and learn how to correctly compile C++.

Or, (shameless plug) I have a generic makefile on github that you can drop in and use on smaller projects with minimal tweaking: https://github.com/mbcrawfo/GenericMakefile
 

Red Squirrel

No Lifer
May 24, 2003
68,458
12,611
126
www.anyf.ca
I can see it become excessive pretty fast if I have a program with like 200 different class/functions. I like to split them up into separate files and folders to make it easier to manage. Having to compile each one individually then having to link them manually sounds like a pain when I can just run a single g++ command like I've always done which compiles and links all in one go.

But just for curiosity sake, how would that be done, as trying to compile something that does not have a main() function will obviously fail.

Actually as I was trying that to ensure that is really the case, I just figured out something. Is it a proper practice to do something like this?

Code:
g++ Main.cpp includes/*.cpp -o binary

It will "include" all the .cpp files automatically that are in the include folder of my program, and I only need to include the .h files in my main program and the .cpp is picked up automatically by specifying the includes/*.cpp at compile time. The only issue I see is this does not seem to recursively search in all sub folders. Is there a flag to tell it to do that?

Never heard of #pragma once, just read up on it and I see no reason not to use it, so I'll switch to that. So I just stick that at the top of all header files and it will ensure it does not get included more than once?
 

postmortemIA

Diamond Member
Jul 11, 2006
7,721
40
91
Compiling them formally one by one is faster since you can use -j flag which compiles source files in parallel.
Whatever you do, compiler will compile each .cpp module separately.
 

Red Squirrel

No Lifer
May 24, 2003
68,458
12,611
126
www.anyf.ca
Ok so if I use -c option I see that it is indeed possible to compile a bare file without a main function and it creates a .o file. Is that what you guys mean by compiling separately?

So how do I go about recurring through my program's folder structure to do this to all the .cpp files? And then what do I do to recursively link them all together into the binary?

I could write a bash script to do that, but is that the proper practice?
 

Merad

Platinum Member
May 31, 2010
2,586
19
81
I can see it become excessive pretty fast if I have a program with like 200 different class/functions. I like to split them up into separate files and folders to make it easier to manage. Having to compile each one individually then having to link them manually sounds like a pain when I can just run a single g++ command like I've always done which compiles and links all in one go.

I don't know how you managed to get this far into C++ without learning how to properly compile programs. D: Of course no one sits there invoking 200+ compiler commands by hand.

I could write a bash script to do that, but is that the proper practice?

No!

Working from the Linux command line, the the canonical build tool is make. There are alternatives, of course, such as CMake (most often used for cross platform projects), or if you use an IDE (Netbeans, Code::Blocks, ...) it manages makefiles for you.

Basic makefiles are fairly simple, but they can quickly get complex, because it's an ancient (40 year old) system.

I recommend you use the generic makefile I linked above. You should be able to drop it in and be ready to use after changing 2-3 settings.
 

Red Squirrel

No Lifer
May 24, 2003
68,458
12,611
126
www.anyf.ca
I know how to compile: g++ source.cpp -o binary. But I'm just looking at improving how I organize my headers as the current way I'm doing it is probably not that great, as it's relying on an external program to itterate through the folders and make two master include files. (one for sources and one for headers). But if it's that complicated to change the way I'm doing it, then I guess I'll just stick to what works.

I was looking at make, but it looks like you still have to specify each file, so I'm really not sure what it does that g++ does not do. What about all the other files that go with the make file? I was reading up on it and there's tons of other files too such as configure etc.
 
Last edited:

Essence_of_War

Platinum Member
Feb 21, 2013
2,650
4
81
I know how to compile: g++ source.cpp -o binary. But I'm just looking at improving how I organize my headers as the current way I'm doing it is probably not that great, as it's relying on an external program to itterate through the folders and make two master include files. (one for sources and one for headers). But if it's that complicated to change the way I'm doing it, then I guess I'll just stick to what works.

I was looking at make, but it looks like you still have to specify each file, so I'm really not sure what it does that g++ does not do. What about all the other files that go with the make file? I was reading up on it and there's tons of other files too such as configure etc.

Hmmm it still sort of sounds like you're not clear on the value of make.

You essentially write your program/projects dependencies into the make file ONCE to automate the building of all dependencies whenever you type "make".

This is THE canonical way to work on on big projects with dependencies, or even small projects with a handful of dependencies, and even huge and important projects (like the Linux kernel and gcc) use it.
 

Red Squirrel

No Lifer
May 24, 2003
68,458
12,611
126
www.anyf.ca
But if I'm working on my own program I'm continuously adding new include files and expanding my folder structure, having to continuously edit the make file too seems like an extra added step. Is there not a way to recurse into a folder and just compile all the cpp files at once? I thought I had it by using *.cpp as a file option in the g++ command, but it does not recurse to sub folders within that folder.

Is there a way to do this with make? Typically I have programname.cpp in the main folder for my project and a rebuild.sh script that just calls g++ with any special flags (libraries etc), then an "includes" folder with all my custom classes specific to my program, so I'd want it to compile everything in there too. If I use the format where each respective .cpp file includes it's own .h file on top, I just need a way to automagically include all the .cpp files and the .h's will automatically be included as well.
 

Red Squirrel

No Lifer
May 24, 2003
68,458
12,611
126
www.anyf.ca
I hate just copy and pasting a bunch of code if I don't know what it does. I found a simpler example but it does not seem to recurse through sub directories as I'm getting an error with a class that is within a folder inside the src folder so it seems to not recurse through more than one level. This is what I have so far:

Code:
CPP_FILES := $(wildcard inc/*.cpp)
OBJ_FILES := $(addprefix obj/,$(notdir $(CPP_FILES:.cpp=.o)))
LD_FLAGS :=
CC_FLAGS :=

testprogram: $(OBJ_FILES)
        g++ testprogram.cpp $(LD_FLAGS) -o $@ $^

obj/%.o: inc/%.cpp
        g++ $(CC_FLAGS) -c -o $@ $<

I have a class in the inc/subclass folder, and it fails with a linker error, so I don't think it's getting picked up.
 

Merad

Platinum Member
May 31, 2010
2,586
19
81
Makes wildcard function is not recursive. You have to use find (see my makefile) or write a recursive version of wildcard (see my makefile).
 

Essence_of_War

Platinum Member
Feb 21, 2013
2,650
4
81
I hate just copy and pasting a bunch of code if I don't know what it does. I found a simpler example but it does not seem to recurse through sub directories as I'm getting an error with a class that is within a folder inside the src folder so it seems to not recurse through more than one level. This is what I have so far:

Code:
CPP_FILES := $(wildcard inc/*.cpp)
OBJ_FILES := $(addprefix obj/,$(notdir $(CPP_FILES:.cpp=.o)))
LD_FLAGS :=
CC_FLAGS :=

testprogram: $(OBJ_FILES)
        g++ testprogram.cpp $(LD_FLAGS) -o $@ $^

obj/%.o: inc/%.cpp
        g++ $(CC_FLAGS) -c -o $@ $<
I have a class in the inc/subclass folder, and it fails with a linker error, so I don't think it's getting picked up.

There are a number of ways to do what you're saying. Merad has outlined two of them above me also.

1) Wildcard'ing the directories

https://stackoverflow.com/questions/4036191/sources-from-subdirectories-in-makefile

2) Using "make" to execute shell commands (like "find")

https://stackoverflow.com/questions/5273374/make-file-with-source-subdirectories

3) Taking advantage of make's recursion my putting a top level make file with a recursive target, and makefile inside each of the sub directories that find their local source files.

http://owen.sj.ca.us/~rk/howto/slides/make/slides/makerecurs.html

All of them should work fine for you. I stress that no one is telling you to copy paste code without understanding it. We're giving you examples and you really should study them along with the make manual to understand precisely what it is doing.
 

uclabachelor

Senior member
Nov 9, 2009
448
0
71
I read about compiling everything into separate object files, but that seems a little excessive. I want to be able to just run a single g++ command to compile the whole program into one binary. I might look into splitting stuff up into separate object files when dealing with larger programs, but that's another topic. I don't actually want to make each and every class a separate object file.

That's why there's tools to do that for you. If it's a program in the *nix environment, use make files. If it's Windows, use any IDE. Any.
 
Last edited:

veri745

Golden Member
Oct 11, 2007
1,163
4
81
I just dropped in to say this.

One of the best lessons I've learned doing c++ development is that you should always try your best to avoid using `#include <blah>.h` in a header file.

If at all possible, use forward declarations instead.

including header files from other header files as a matter of course leads to Pain and Suffering&#8482;

Like others have said, building your whole program in a single g++ command is not ideal for a project of any reasonable size. Use a build tool like make, CMake, Gradle, Scons (if you're from the 90s), or one of the dozens of other similar tools that are available.
 
Last edited:

Red Squirrel

No Lifer
May 24, 2003
68,458
12,611
126
www.anyf.ca
I just dropped in to say this.

One of the best lessons I've learned doing c++ development is that you should always try your best to avoid using `#include <blah>.h` in a header file.

If at all possible, use forward declarations instead.

including header files from other header files as a matter of course leads to Pain and Suffering™

Like others have said, building your whole program in a single g++ command is not ideal for a project of any reasonable size. Use a build tool like make, CMake, Gradle, Scons (if you're from the 90s), or one of the dozens of other similar tools that are available.

Yeah but at some point the include still needs to be there. The forward declaration is still counting on the class to actually be part of the program.

Also I'm not sure what is the reasoning that you should not just set it up so a single g++ command can compile the program, cmake and all these things just seem to overcomplicate the entire process, I'm just trying to figure out what the advantage actually is.
 
sale-70-410-exam    | Exam-200-125-pdf    | we-sale-70-410-exam    | hot-sale-70-410-exam    | Latest-exam-700-603-Dumps    | Dumps-98-363-exams-date    | Certs-200-125-date    | Dumps-300-075-exams-date    | hot-sale-book-C8010-726-book    | Hot-Sale-200-310-Exam    | Exam-Description-200-310-dumps?    | hot-sale-book-200-125-book    | Latest-Updated-300-209-Exam    | Dumps-210-260-exams-date    | Download-200-125-Exam-PDF    | Exam-Description-300-101-dumps    | Certs-300-101-date    | Hot-Sale-300-075-Exam    | Latest-exam-200-125-Dumps    | Exam-Description-200-125-dumps    | Latest-Updated-300-075-Exam    | hot-sale-book-210-260-book    | Dumps-200-901-exams-date    | Certs-200-901-date    | Latest-exam-1Z0-062-Dumps    | Hot-Sale-1Z0-062-Exam    | Certs-CSSLP-date    | 100%-Pass-70-383-Exams    | Latest-JN0-360-real-exam-questions    | 100%-Pass-4A0-100-Real-Exam-Questions    | Dumps-300-135-exams-date    | Passed-200-105-Tech-Exams    | Latest-Updated-200-310-Exam    | Download-300-070-Exam-PDF    | Hot-Sale-JN0-360-Exam    | 100%-Pass-JN0-360-Exams    | 100%-Pass-JN0-360-Real-Exam-Questions    | Dumps-JN0-360-exams-date    | Exam-Description-1Z0-876-dumps    | Latest-exam-1Z0-876-Dumps    | Dumps-HPE0-Y53-exams-date    | 2017-Latest-HPE0-Y53-Exam    | 100%-Pass-HPE0-Y53-Real-Exam-Questions    | Pass-4A0-100-Exam    | Latest-4A0-100-Questions    | Dumps-98-365-exams-date    | 2017-Latest-98-365-Exam    | 100%-Pass-VCS-254-Exams    | 2017-Latest-VCS-273-Exam    | Dumps-200-355-exams-date    | 2017-Latest-300-320-Exam    | Pass-300-101-Exam    | 100%-Pass-300-115-Exams    |
http://www.portvapes.co.uk/    | http://www.portvapes.co.uk/    |