I have been looking around but I have not found any question that really helps me to solve this issue. I am not very experienced, so maybe this problem is trivial and it is a question of my lack of knowledge.
I am trying to solve an issue. Our system has a Logger that takes different logs and puts them into a SharedMemory.
However, from one of our classes (a StateMachine) I can not use the Loogger because of recursion:
Logger.h includes SharedMemory.h
SharedMemory.h includes StateMachine.h
If I include Logger.h in StateMachine.h, compile errors appear everywhere. First i was trying to fix this problem by creating a second SharedMemory that is dedicated exclusively to the Logger and don't include StateMachine.h.
With this approach, the compilation errors were solved, but my manager does not like this design solution.
I have also tried to change include order, and to declare class before the include but it is not working (e.g. declare class SharedMachine; before #include SharedMachine.h)
The includes are like this:
In the StateMachine.h
#ifndef SM_H
#define SM_H
#include <map>
/* (different includes) */
#include Logger.h
In the Logger.h
#include SharedMemory.h
In the SharedMemory.h
#include StateMachine.h
I would like to know if there is any trick that I can use to make the includes work in this way, without architectural changes (that my manager seems not to like).
Try to move includes from header files to source (*.cpp) files
Use forward declarations: What are forward declarations in C++?
Change interfaces to work with pointers or references to needed types instead of using actual types, to make possible using forward declaration (if needed)
Related
I am aware of the technicality that arises when someone uses templates in C++ classes/structs but still wants to follow the accepted (quite established) approach of splitting declarations into header(.hpp) files from definitions into source(.cpp) files.
I have done a mini-research in different blogs/forums, searching for a safe and systematic way to adopt and split the declarations from the definitions.
From this, (see answer 1) I am almost convinced that it is not a trustworthy approach to write a template class library and distribute it with header and lib files to hide the implementation. So, only the safe way to go is to directly write the definitions and the declarations in the same file (.hpp).
However, in another blog here I saw a workaround approach, that suggests doing a kind of circular dependency between the source and header files.
By "circular dependency" I mean to include at the bottom of the header file the source code #include "Input.cpp", and as usual, in the source code include the header file #include "Input.hpp" on the top.
This is the example header file:
#ifndef INPUT_H_
#define INPUT_H_
template <class T>
class Input
{
public: // Constructors:
Input(T whatever);
};
#include "Input.cpp"
#endif
and this is the example source code:
#ifndef INPUT_CPP_
#define INPUT_CPP_
#include "Input.h"
template <class T>
Input<T>::Input(T whatever)
{
/* some code here */
}
#endif
According to the answers that I found, the only issue in the circular dependency approach is the double-definition issue, which was resolved by adding preprocessor definitions in both files!
Now, my question is: Is it indeed a good practice to adopt, or maybe because of its simplicity (we used a very simple test case) it fails to prove that it is actually a bad approach?
Can someone provide evidence to show if this circular-dependency approach has any limitations?
Hi I am trying to find a way to prevent the inclusion of platform specific header file for example windows.h.
Curiously none of the solution I found are not satisfactory to me. Maybe it can't be achieved.
I think to achieve this goal several technique need to be used. And there is a lot of example on internet but I couldn't found any about one aspect. Something has to talk/create to your abstraction. Here is an example:
This is a really simplified version of a render window render target.
//D3D11RenderWindow.h
#include <d3d11.h>
class D3D11RenderWindow: public GfxRenderWindow
{
public:
bool initialize(HWND windowHandle);
private:
HWND windowHandle_; /// Win32 window handle
};
That is not so much the problem, this is a platform specific code that get included only by platform specific code. But we need to actually instanciate this type so an "entry point" need to know about the platform specific code too.
For example a factory class:
//GfxRenderWindowFactory.h
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
class GfxRenderWindow;
class GfxRenderWindowFactory
{
public:
static std::unique_ptr<GfxRenderWindow> make(HWND windowHandle);
};
Now this factory class need to be included by the "client" of the library (here a renderer). What I don't like is that #include "windows.h", because it is too error prone to me, anybody that include it, even if they don't need it will have all the world and windows.... Precompile header is not a solution because now it is enforced by the compiler that all cpp have include it (it is a valuable tool to speed compile time but not a tool to separate platform specific code from the portable code)
What I thought is to put the #include in the cpp before the include of its header instead of in the header file like this:
//GfxRenderWindowFactory.cpp
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#include "GfxRenderWindowFactory.h"
/// Implementation of GfxRenderWindowFactory goed here ....
This way it force anybody that want to use this class to include the relevant platform specific header and they will be in better position to judge if they are including this header in a bad place like in one of their own header file.
What are your solution for this?
What do you think of my solution?, crazy?
I want to point out that to me it is of the uberimportance to do portable code right! Answer like just include windows.h and don't sweat about it is not a valid answer. It is not a good coding practice to me.
I hope i made my question clear. If not tell me i'll clarify
Thanks a lot!
## Edit ##
From a small conversation with hmjd I would like to keep the inclusion of windows.h in the header file since, i agree, this make it way more usable. So it would be nice to have a way to prevent the inclusion in a header file and this way enforce that the file can only be included in a cpp. Is this possible?
Is using a predefined macro, like WIN32, or a macro defined by your build system not sufficient:
#ifdef WIN32
#include <windows.h>
#else
include other platform specific headers
#endif
This is a common approach (and FWIW the only approach I have ever used).
Since the underlying issue is passing an HWND to GfxRenderWindowFactory::make, don't have GfxRenderWindowFactory::make take an HWND.
Hey I worked on the wxsmith cross-platform GUI API. The first thing that you need to do is create classes with your own handles. A handle is 1 of 3 things:
A void *.
Class *.
Struct *.
Use a function like so:
#define create_handle(handle) struct __##handle{unsigned int unused;}; typedef __##handle *##handle;
Then call this function and it creates a struct and a pointer to a struct. The pointer is the handle. Then cast to whatever you desire reinterpret_cast(your handle here); and your done then you can cast like this in your object files or your libs or dlls. And make a global define for your window handle, research how other OS's do it and you done.
I'm using a custom library in a c++ project, witch includes several std headers, but when i include the corresponding header in the main file, it's like i included all the headers in the custom one.
To be clear:
custom header file:
#ifndef CUSTOM_H
#define CUSTOM_H
#include <vector>
//stuff
#endif
Main.cpp:
#include <iostream>
#include "custom.h"
//here, let suppose that i do next:
vector<int> vec;
return 0;
there's no compile error, like the vector header is included, i want to avoid that, any suggestion
If custom.h's use of std::vector is an implementation detail (and not exposed in the signatures of things you define in the header), consider moving the #include <vector> to the corresponding custom.cpp file instead.
If you can't move the include out of custom.h because, say, you pass a vector in or out of a method, then it truly is part of your interface and clients of your header will need to know about it.
It is possible, but this shouldn't be done without consideration because it gives meaning to the order in which you include files, that is, you will or won't be able to compile depending on what order your #includes are in. It is generally desirable to avoid that situation.
To accomplish that, remove #include <vector> from the .h and add it to Main.cpp above where you include the custom header file. If you #include it below that, it will complain about types being undefined. Also in every file that uses the custom header file, they will have to #include <vector> first.
The problem is nearly unavoidable. If your header file needs to include another for any reason whatsoever, there's no way to "uninclude" it later.
There's one technique that can minimize the problem, the pimpl idiom or opaque pointer. By moving the implementation of a class into a private source file, you eliminate the dependencies that caused you to include the header in the first place.
I have 3 classes (it could be 300) , each one with its own header and implementation.
I'd like to write an 'elegant' way to organize the way I load of any class needed by every class of the three. Maybe this example helps...
I have : class1 class2 class3
Every header has:
#ifndef CLASS#_H
#define CLASS#_H
#define FORWARD_STYLE
#include "general.h"
#endif
Every implementation has:
#define DIRECT_STYLE
#include "general.h"
OK
I'm going to write a 'general.h' file in which I'd have :
#ifndef DIRECT_STYLE
#ifndef CLASS1_H
#include "class1.h"
#endif
#ifndef CLASS2_H
#include "class2.h"
#endif
#ifndef CLASS3_H
#include "class3.h"
#endif
#endif
#ifndef FORWARD_STYLE
class Class1;
class Class2;
class Class3;
#endif
// a lot of other elements needed
#include <string.h>
#include <stdio.h"
....
#include <vector.h"
( all the class I need now and in the future )
This is a good structure ? Or I'm doing some idiot thing ?
My goal is having one unique 'general.h' file to write all the elemenst I need...
Are this to work fine ?
Thanks
The basic rules to follow are:
Let each of your source file include all the header files it needs for getting compiled in a standalone manner. Avoid letting the header files include in the source file indirectly through other files.
If you have constructs which will be needed across most source files then put them in a common header and include the header in Only in those source files which need it.
Use Forward declarations wherever you can.There are several restrictions of when you can get away using them,read this to know more about those scenarios.
Overall it is a good idea to avoid including unnecessary code in source files through a common header because it just results in code bloat, so try and keep it to a minimum. Including a header just actually copy pastes the entire header to your source file and Including unnecessary files has several disadvantages, namely:
Increase in compilation time
Pollution of global namespace.
Potential clash of preprocessor names.
Increase in Binary size(in some cases though not always)
This might like a fine idea now, but won't scale and should be avoided. Your general.h file will include a vast amount of files, and thus all files that include it will (a) take ages to compile or not compile at all due to memory restrictions and (b) will have to be re-compiled every time anything changes.
Directly include the headers you need in each file, and define a few forward declaration files, and you should be fine.
The #define in a header will probably be ok, but it can propagate through lots of sources and potentially cause problems. More seriously, any time general.h or any of its includes change your entire project rebuilds. For small projects this isn't an issue, for larger projects it will result in unacceptable build times.
Instead, I utilize a few guidelines:
In headers, forward declare what you can, either explicitly or with #include "blah_fwd.h" as seen in the standard library.
All headers should be able to compile on their own and not rely on the source file including something earlier. This can be easily detected by all source files always including their own header first.
In source files, include what you need (usually you can't get away with forward declarations in source files).
Also note to never use using in headers because it will pollute the global namespace.
If this seems like a lot of work, unfortunately that's because it is. This is a system inherited from C and requires some level of programmer maintenance. If you want to be able to decide at a high level what's used by your project and let the compiler/runtime figure it out, perhaps C++ isn't the right language for your project.
I keep running into problems the larger my program gets. For instance, I get the following error:
In file included from WidgetText.h:8,
from LCDText.h:17,
from WidgetText.cpp:13:
Generic.h:21: error: expected class-name before ',' token
Here are those lines:
#include "Generic.h" // WidgetText.h:8
#include "WidgetText.h" // LCDText.h:17
#include "LCDText.h" // WidgetText.cpp:13
class Generic: public virtual LCDText, public CFG, public virtual Evaluator { // Generic.h:21
Here are the contents of the various header files:
//Generic.h
#include "CFG.h"
#include "Evaluator.h"
#include "LCDText.h"
#include "Widget.h"
//WidgetText.h
#include "Generic.h"
#include "Property.h"
#include "Widget.h"
//LCDText.h
class Generic;
#include "LCDBase.h"
#include "WidgetText.h"
This isn't providing much; I know. I'm not sure what else to include. Each header defines a class named after its header, so LCDText.h has a class named LCDText.
The one line declaring class 'Generic' in LCDText.h had to be placed there due to an earlier problem similar to this one. I'm assuming this current issue has a similar solution, but I've failed to find it thus far.
You have a circular dependency: Generic.h includes LCDText.h which includes WidgetText.h which includes Generic.h; the error stems from this basic problem. If you can rework your headers to eliminate this cycle, chances are the error will either resolve itself in the refactoring or the problem will become much more obvious than it is now.
From the code presented here, it seem that you are include the header filed multiple times. To prevent problems you need conditional guards in your header files.
Part of the solution is to add some forward declarations to get rid of these compiler errors (just like you did with your class Generic line). Google will turn up lots of suggestions on how exactly to do this.
Using forward declarations will let you eliminate the cyclic / circular #includes described in this answer.
A forward declaration lets you include references to and pointers to the forward-declared class, and it lets you pass the forward-declared class as a parameter, but it does not let you derive from or include an instance member of the forward-declared class. So your Generic class needs a way to #include (and not just forward-declare) the header files for LCDText, CFG, and Evaluator. If it can't do that because LCDText, CFG, or Evaluator need to #include (and not just forward-declare) Generic, then you need to rearrange your hierarchy to fix this (for example, by making a member variable a pointer or reference to a class instead of making it an instance of a class).
However, using multiple inheritance like this (and especially using the diamond inheritance implied by two virtual inheritances) is a definite code smell. It suggests that you should be designing your class hierarchy differently. For example, maybe you need to be favoring composition over inheritance. That would make cleaning up your forward declarations and cyclic dependencies a lot easier.
Edit: You mentioned that you've been running into this problem more as your code base gets larger. I'm told that John Lakos's Large-Scale C++ Software Design is a good reference for managing issues such as header file dependencies in large projects, although it may be overkill for where your project is right now.
Others have already pointed out the circular dependency but if you're still unsure of how to fix it then it looks for all the world as if you need to forward declare Generic in WidgetText.h i.e. line 8 becomes
class Generic;
If you've already tried that, and it sounds as if you have, then you need to examine how you are using Generic in WidgetText.h and see if you can eliminate places where you are relying on having the full definition eg. change an aggregated Generic to a Generic* or move an inline member that accesses a Generic method into an out-of-line definition in a source file.