My team and I are working on a pretty large project with many classes with their respective header and source files. We are trying to consolidate all includes from both C++ libraries and the projects class header files into one file called "Includes.h" which is included in every header file. One problem I have encountered when doing this is that the class header files are basically including themselves. I have included #pragma once at the top of every header file. When I comment out the #include "Controller.h" in the "#Includes.h" file, the errors for "Controller.h" go away.
Please Please Please and Pretty Please do not do this.
Prefer forward declarations. Then the individual include files.
Otherwise you change one include file and it has to compile the lot. I.e. waste of time.
Bascially get each header file to be able to compile with a blank cpp file. Minimum dependecies.
Related
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.
I was recently looking through the source code of a C++ application and saw that each class did not #include its needed components, but instead #include'd a "Precompiled.h" header. In this Precompiled header was an inclusion of almost every header in the application (not all of them, it was clear that the length and order of the list was deliberate). Essentially, this would mean that every class had an inclusion of every other class in the application.
Is this wise? Why or why not?
Usually if you write an application, you should only include header files which are really needed in cpp files. If you got a really big application, you should use forward declaration in the header and include necessary files in the cpp file. With that, changes in code only affects a minimum on cpp files, so the compiler had only to compile what really has changed.
The situation can totally flip, when it comes to libraries or code which does not change very often. The filename "Precompiled.h" is already a hint. The compiler can precompile the headers to a special object file, often called PCH file. With that, the compiler has not to resolve every include on every compile time. On heavy nested includes, this has high impact on compile speed, because instead of many files to load and parse, there is only one preparsed file. To archive that you have to declare one or more headers as a kind of center file for building a precompiled header. How you do that differs between different compilers.
For example Visual studio uses the header file "stdafx.h" as the center of the precompilation of header files. Because of that, only header files should include there which are not altered very often. Also the file had to be included first in every cpp file. That is because the compiler can not detect any more if a include file which is included before may have influence to the precompiled file. To avoid that, includes before the precompiled includes are not allowed.
Back to your question. Including every file in one header file to use it as precompiled header makes no sense at all, as it conteract the meaning of a precompiled header file.
It is a very bad idea.
For a .cpp file only include the minimum number of #include files.
Thereby when one of them changes the make (or moral equilivant) will not require the whole lot to be recompiled.
Saves lots of time during development.
PS Use forward declarations in preference to #include
I encountered this problem, Usually you all are going to ask me the why, so I'll explain first so you can just answer me, I'm working on a source with at least 500.000lines but now one of my source (.cpp) files I just created must NOT add the precompiled header which is "StdAfx.h" in this case, I must NOT edit the project precompiled header settings, obviously if I try to compile my the project without including stdafx in the new file i'll be smashed with a C1010, what I've tried is this
StdAfx.h:
#ifndef __ABC123
//do all your includes
#endif
MyFile.cpp:
#define __ABC123
#include "StdAfx.h"
#undef __ABC123
Althought, this doesn't works, stdafx.h is still including the files. Why I can't have stdafx.h includes on this .cpp file is because some includes on stdafx have tons of conflicts with the includes of this cpp. I can't modify the stdafx includes because thousands of other files use it, how to deal with this?
Impossible. You have painted yourself in to a corner here. Let me 'splain.
PCHs are intended to be used across an entire project. Every translation unit is expected to include the PCH.
This behavior can be overridden, but only via the project settings for the translation unit in question. You have already said that you must not edit the project settings, hence eliminating your only avenue of escape.
If you really need this and there's no way out, I would consider taking such drastic steps as moving the non-PCH code in to its own project.
Since I got multiple classes and utility-functions I reuse on a regular basis, I started to create a static library for those parts.
Until now, most of those header files with class and function declarations #include the same "global" header file which itself #includes other header files (like <string> <windows.h> etc.).
As for me, It feels annoying to force a user to include more than one header file when only "actively" using the one which got the classes.
So I vanquished the global header file and included all the necessary headers into my own headers.
This worked in some way, but I encountered some problems regarding Winsock:
You need to #define WIN32_LEAN_AND_MEAN and ensure that the user won´t #include <windows.h> before those headers of mine, or multiple redefinitions will occur :/.
That´s why I wanted to ask You how You would do this? Or what approches You can think of?
I think you only have the option of defining a general header file that all other header files include and that defines WIN32_LEAN_AND_MEAN.
Otherwise you could instruct the user to include such definition in his own files, but his would be error prone.
As to inclusion of <windows.h> I think that it will not be included multiple times, since it has "include guards".
I have a large C++ file (SS.cpp) which I decided to split in smaller files so that I can navigate it without the need of aspirins. So I created
SS_main.cpp
SS_screen.cpp
SS_disk.cpp
SS_web.cpp
SS_functions.cpp
and cut-pasted all the functions from the initial SS.cpp file to them.
And finally I included them in the original file :
#include "SS_main.cpp"
#include "SS_screen.cpp"
#include "SS_disk.cpp"
#include "SS_web.cpp"
#include "SS_functions.cpp"
This situation remains for some months now , and these are the problems I've had :
The Entire Solution search (Shift-Ctrl-F in VS) does not search in the included files, because they are not listed as source files.
I had to manually indicate them for Subversion inclusion.
Do you believe that including source files in other sources is an accepted workaround when files go really big ? I should say that splitting the implemented class in smaller classes is not an option here.
There are times when it's okay to include an implementation file, but this doesn't sound like one of them. Usually this is only useful when dealing with certain auto-generated files, such as the output of the MIDL compiler. As a workaround for large files, no.
You should just add all of those source files to your project instead of #including them. There's nothing wrong with splitting a large class into multiple implementation files, but just add them to your project, including them like that doesn't make much sense.
--
Also, as an FYI, you can add files to your projects, and then instruct the compiler to ignore them. This way they're still searchable. To do this, add the file to the project, then right-click it, and go to Properties, and under "General" set "Exclude from Build" to Yes.
Don't include cpp files in other files. You don't have to define every class function in one file, you can spread them across multiple files. Just add them individually to the project and have it compile all of them separately.
You don't include implementation (.cpp) files. Create header files for these implementation files containing the function/class declarations and include these as required.
There are actually times you will want to include CPP files. There are several questions here about Unity Builds which discuss this very topic.
You need to learn about Separate compilation, linking, and what header files are for.
You need to create a header file for each of those modules (except possibly main.cpp). The header file will contain the declarative parts of each .cpp source file, and the .cpp files themselves will contain the instantive parts. Each unit can then be separately compiled and linked. For example:
main.cpp
#include "function.h"
int main()
{
func1() ;
}
function.h
#if !defined FUNCTION_H
#define FUNCTION_H
extern void func1() ;
#endif
function.cpp
void func1()
{
// do stuff
}
Then function.cpp and main.cpp are separately compiled (by adding them to the sources for the project), and then linked. The header file is necessary so that the compiler is made aware of the interface to func1() without seeing the complete definition. The header should be added to the project headers, then you will find that the source browser and auto-completion etc. work correctly.
What bothers me with this question is the context of it.
A large cpp file has been created, large enough to warrant thinking about splitting it into smaller more manageable files. The proposed split is:
SS_main.cpp
SS_screen.cpp
SS_disk.cpp
SS_web.cpp
SS_functions.cpp
This seems to indicate that there are separate units of functionality from a specification and design perspective. We can only guess at the coupling between these units of code.
However, it would be a start to define these code units such that each new cpp file has its own header file thus defining the interfaces of these units and the (low) coupling between them to achieve (high) cohesion for each unit.
We are refactoring here.
It is not acceptable to use included cpp files in this context it as does not provide any advantages. The only time I've come across included cpp files is when a one is included to provide code for debug code, and example being to compile non-inline versions of functions. It helps in stepping through code in the debugger.