C++ Header and Source file design implementation - c++

I have a few queries regarding the design principle of laying out a C++ header and source files:
I have recently taken over a project in which the previous programmer used to have this, which is particularly annoying because I read somewhere that we shouldn't include a .cpp file in a .hpp file (The preprocessor will just copies and pastes the .cpp file into a .hpp)
Q1. Including a .cpp file in a .hpp file is bad? why?
Due to the problem above, I am facing many "multiple declaration" errors when I load my program in eclipse, even though i added the header guards in all the .hpp files.
Q2. Should i be including the header guards in the .cpp files as well?
I tried the later too but to no avail. Any suggestions on this?
Q3. If 2 or more of my .cpp files need the same header files to be
used what is the best way to include all those header files? Should i
create a new header file say h1.hpp, include all the header files I
need in those 2 or more .cpp files and later include in this header
file in those .cpp files(s)?
Is it an efficient approach ?

Including a .cpp file in a .hpp file is bad? why?
In a typical code setup, yes. It serves no useful purpose and can lead to "duplicate definition" errors.
More importantly, it mixes the separation between the implementation and interface parts. When a file containing implementation is meant to be included, it's often changed to .inl (from "inline") extension.
Should i be including the header guards in the .cpp files as well?
No. Header guards prevent two (or more) other headers in one translation unit from including the same header twice. Since there's only one .cpp file per translation unit, this problem doesn't occur there.
To illustrate, an example inclusion could look like this:
common.hpp
/ \
/ \
A.hpp B.hpp
\ /
\ /
file.cpp
In this case, header guard in common.hpp prevents it from appearing twice in the TU introduced for file.cpp.
If 2 or more of my .cpp files need the same header files to be used what is the best way to include all those header files?
You shouldn't be scared by a long include chain, in general. It's less scary than it looks. That being said, "aggregate" headers can be used if the headers actually form a tree structure (to make including subsets easier, like collections.hpp and collections/vector.hpp + collections/list.hpp) or to include every header from the library.

Related

C++ Struct prototyping in separate header file

I am having trouble understanding an answer I saw in another post. It said that it is good practice to define a struct in a separate .h file so it can be used in other files. I think that is great and it solves my current dilemma, however I have a question about compilation and makefiles. I am only familiar with having header files that are associated with .cpp files at the moment.
Can someone explain how that implementation would look when I have a .h and no .cpp? Do I need an implementation file as well? Also, how do I link the header in a makefile? Currently I only know how to compile a .cpp & header into a .o file and link them.
Thanks, and sorry for taking us back to c++ kindergarten. This is a new revelation and seems like a good one.
You don't need a matching source file (.c or .cpp) for every header .h file.
Having header files without corresponding source files is just fine.
When you #include some header file, you can think of it as a kind of "copy and paste" operation: the preprocessor copies the content of the header file, and pastes it in the point of inclusion.
(Well, there are some details to consider here, for example the presence of a #pragma once directive or some #ifdef inclusion guard can prevent multiple inclusions of the same header file in a given project.)
The C and C++ compilers will then process the whole "compilation unit", i.e. the current source file with all the included headers.
The key concept is that you define the struct/class in a .h header, so that you can use it in multiple .cpp files. Whenever you need struct foo defined in foo.h, you #include "foo.h". You don't need to directly compile the header file, it will be pulled in by whichever source file uses it. Therefore you don't need a make target for .h in normal circumstances.
If the definition in the header is never used, it won't be pulled in and that's it.

Where to #include headers?

I looked up header file examples, but could only find simple ones with nothing to include.
So my question is where do I #include stuff like string and vector? In the .h or the .cpp file? Or maybe in both?
Anywhere you need.
If you need something declared in a header file, include them in the .h file.
Otherwise just in the .cpp file.
Note that including a .h file is just a textual replacement and the contents of the included .h file will be entirely inserted at the beginning of the file where they've been included. at the precise point of the #include line.
It is good practice to include a project-belonging headers before the standard library ones and never include a header if you don't need it.
Last thing you should keep in mind is that when working with large projects including many headers in a .h file shared by many translation units can increase compilation times if the header gets modified. It's usually preferred to just include what you strictly require in the appropriate files (either .cpp or .h). Precompiled headers might also help but it's off-topic to your question.
Finally: don't rely on "this header has been included somewhere else and I'm already including it through a second header" because it could render dependencies-tracking hard and favor circular dependencies when the project grows.
where do I #include stuff like string and vector? In the .h or the .cpp file?
There are multiple issues to consider in this, especially when projects get bigger (i.e. the bigger your project is, the more this affects you).
Personally, I follow these rules:
if code needs a header to compile, then you need to include it (if header declares things with std::string in the API, you will have to include string and the same goes for the C++ file)
do not include headers that are not needed (i.e. not "both" - if you include a header in your .h file, then include your .h file, you should be fine).
organize headers prioritizing for your project's files. this means if you have in a C++ file local project headers, and std and boost headers, you should (probably) include local project headers first, then boost, then std.
This is because the std headers will be the most tested/stable ones, and the most used API (this is a blind supposition on my part). If you were to include std headers first, and then project headers (for example), since the replacement is textual, you could get away with not adding the include in the project header. This would basically mask an error, because you would end up having to include the std headers before the local project header in all other cpp files from now on.

The role of a header file in compilation?

We have been asked a question in a practice paper 'What is the role of the header file in compilation? What are header guards used for in this context?'
A header file will have any declarations for classes which may be included in .cpp implementations. I understand that by including a header file in an implementation or other header file, it is possible for that code to know all the possible members of the class without knowing its implementation.
Having done a little reading through StackOverflow, some have suggested that header files can possibly slow down compilation (Coding C++ (mostly) in header files vs .cpp files) and that while a change to a header file will require a full rebuild of all implementations, while a change to an implementation does not require a full rebuild of the header file and all its implementations.
Would these be accurate? Is there any reason that a header file is necessary of beneficial in compilation and what role does it play?
Many thanks!
yes, although I would avoid using the term implementations for code files - people may think you are talking about the implementation of the class(es) in the headers, which could lead to confusion.
Also, changing a header file will not result in you needing to rebuild all the code files - only those which include (directly or otherwise) said header file.
Oh, and header guards are used to avoid the same file being included twice in a given compilation unit (resulting in redefinitions of things).

Headers without cpp files and include ordering

There was a highly rated response in a question about header ordering with the following suggestion:
Good practice: every .h file should have a .cpp that includes that .h first before anything else. This proves that any .h file can be put first.
Even if the header requires no implementation, you make a .cpp that just includes that .h file and nothing else.
Personally I've never had a problem with include ordering for headers that don't have a corresponding cpp file. What kinds of problems does this best practice prevent?
The header file should compile on itself. ie. for testing make a .cpp file that just includes the header file.
The header file should be guarded by the pre-processor. if #ifndef etc...
Both these will ensure that the order will not matter.
One problem it solves is allowing the .h file to be linted (at least by my lint tools). Without a .cpp doing an include of an .h my template code gets skipped.

CPP | .h files (C++)

I was just wondering what the difference between .cpp and .h files is? What would I use a header file (.h) for and what would I use a cpp file for?
In general, and it really could be a lot less general:
.h (header) files are for declarations of things that are used many times, and are #included in other files
.cpp (implementation) files are for everything else, and are almost never #included
Technically, there is no difference. C++ allows you to put your code in any file, with any format, and it should work.
By convention, you put your declarations (basically, that which makes up your API) in the .h files, and are referred to as "headers". The .cpp files are for the actual "guts" of your code - the implementation details.
Normally, you have the header files included with #include by other files in your project (and other projects, if you're making a library), so the compiler can get the interface required to compile. The implementation, in the .cpp files, is typically implemented so there is one .cpp file "filling in" the implementation per .h file.
By convention, .h files is something that you #include. CPP files are something you add to your project for compiling into separate object file, and then passing to the linker.
The .h file is called the header file. You usually put your interface there (the stuff you want to be public). The cpp file is where you actually implement your interface.
First, both are text files that contain code for the C++ compiler or pre-processor. As far as the system is concerned there is no difference.
By convention different file name extensions are used to indicate the content of files. In C programs you tend to see .h and .c files while in C++ .hpp and .cpp serve the same purposes.
The first group, .h and .hpp files, called header files, contains mostly non-executing code such as definitions of constants and function prototypes. They are added to programs via #include directive and used not only by the program or library in question but by other programs or libraries that will make use of them, declaring interface points and contracts defining values. They are also used to set metadata that may change when compiling for different operating systems.
The second group, .c and .cpp files, contain the executing parts of the code for the library or program.
Correct me if I'm wrong but,
When you #include something, it more-or-less inserts the entire included file into the one with the include command; that is, when I include, say "macros.h" in "genericTools.cpp", the entire contents of "macros.h" is placed in "genericTools.cpp" at that point. This is why you need to use things like "#pragma once" or other protections, to prevent including the same file twice.
Of note, templated code needs to be entirely in the file you're going to be including elsewhere. (I'm unsure of this - can template specializations be ommited from the included files, and linked like a normal function?)
The .cpp that is the implementation file is our actual program or code.
When we need to use different inbuilt functions in our code, we must include the header file that is .h files.
These .h files contains the actual code of the inbuilt functions that we use hence we can simply call the respective functions.
Therefore, while we compile our code we can see more number of lines compiled than what we have actually coded because not only our code is compiled but along with that the (code of the) functions (that are included in .h files) are also compiled.