Today, a colleague inquired if there is a technical reason to #include headers before forward declaring a class in a header. Specifically, I'm not interested in the order of #includes within themselves or the merits of forward declare vs #includes, but on any technical reasons one order is preferred over the other.
Example: Assume companions.h is correct in that it requires donna.h and clara.h to be #include and CSpaceTimeContinuum and CTardis can be forward declared. Is it better to #include then forward declare?
// companions.h
#include "donna.h"
#include "clara.h"
class CSpaceTimeContinuum;
class CTardis;
or forward declare then #include?
// companions.h
class CSpaceTimeContinuum;
class CTardis;
#include "donna.h"
#include "clara.h"
If there's no technical difference and it is a stylistic thing only, I would be happy to learn that as well. Thank you!
Always headers first, then forward declares. Otherwise you risk unnecessary dependencies such that you'll need to repeat the forward declares whenever you include donna.h, for example (because you have inadvertently introduced a need for it).
"donna.h" and "clara.h" should be constructed so they do no depend on external forward declarations, which leaves just one practical possibility that there could be a collision between CSpaceTimeContinuum and CTardis declared in any of those files and your usage of those classes in the local source. The only difference then in order of lines could make is diagnostics in case of collision.
Related
I'm not very familiar with C++, and this is my first time working with more than just the namespace std. What is the difference between the following?
using MyNameSpace::MyClass;
vs
namespace MyNameSpace {class MyClass;}
After both, it seems I can now create a MyClass object. Is one way better than the other? Also, if I don't do either, can I still reference MyClass by appending MyNameSpace::MyClass before it every time I need to?
Next, if I forward declare using the second option, do I still need to #include "MyClass.h"? In my (not very good) understanding, in C++, you make header files in order to forward declare classes so that they can be used later. So if you have already forward declared, would you still need to include the header file?
Finally, when working with multiple namespaces (namespace Architecture and namespace Router), I have an error I don't know how to explain. In one of my header files, I have using std::vector as the first line after my #include statements. This statement is not within any namespace, I think. When compiling, I receive the error, "'Architecture::std::vector' has not been declared". To remedy this, I can change the statement to using ::std::vector to tell it to look at global scope for std::vector.
However, I don't understand why this problem exists. Since I am declaring using std::vector at the top of my header file, why am I not already at global scope? A better question might be: how can I tell which scope I am in at the top of a header file? Additionally, I thought in C++ (and according to this answer What is the difference between writing "::namespace::identifier" and "namespace::identifier"?), if you couldn't find the name within the current scope, you would automatically look up a level until you reach global scope.
I hope these questions are well written and understandable. Hopefully I can get some answers to these questions and begin to understand how namespaces interact with one another.
using MyNameSpace::MyClass;
This using-declaration injects the name MyClass into the current scope, referring to the entity denoted by MyNameSpace::MyClass, which must have been previously declared.
namespace MyNameSpace {class MyClass;}
This is a forward declaration of the class MyClass in the namespace MyNamespace.
After both, it seems I can now create a MyClass object.
Unlikely in the second case, unless you have a using namespace MyNamespace; and the full definition of MyClass is available.
Is one way better than the other?
They do completely different things.
Also, if I don't do either, can I still reference MyClass by appending MyNameSpace::MyClass before it every time I need to?
If using MyNameSpace::MyClass; compiles (i.e., MyNameSpace::MyClass has been declared), then you can do this. Otherwise, you can't.
Next, if I forward declare using the second option, do I still need to
#include "MyClass.h"? In my (not very good) understanding, in C++,
you make header files in order to forward declare classes so that they
can be used later. So if you have already forward declared, would you
still need to include the header file?
Headers usually carry the full class definition - which includes declarations of all its data members and member functions. A forward declaration like class MyClass; will not allow you to create a MyClass object, since the compiler would not know how much memory to allocate for that object or what constructors are available.
However, I don't understand why this problem exists. Since I am
declaring using std::vector at the top of my header file, why am I not
already at global scope? A better question might be: how can I tell
which scope I am in at the top of a header file? Additionally, I
thought in C++ (and according to this answer What is the difference
between writing "::namespace::identifier" and
"namespace::identifier"?, if you couldn't find the name within the
current scope, you would automatically look up a level until you reach
global scope.
This sounds like a problem of missing braces. If a header you wrote did not close namespace Architecture, then anything you include after that header will be put into the Architecture namespace by accident. If that's not the problem, please post a MCVE.
Hello I'm new to C++ so bear with me, I'm making a header for a class and I just want to know if I plan on making an object from another class in this one should I include that in the header? for example
class myClass1{
public:
"constructor and methods here"
private:
OtherClass oc;
"other variables here"
};
I know this is a pretty simple question but I can't seem to find the answer anywhere. Any help would be appreciated!
Since as you say that you are new at C++, this might seem a bit overkill for your immediate needs. Keep in mind what I'm trying to teach you is not how to hack this thing up right now, but good coding skills that will transfer to future projects and real work.
A stretch goal, and a general rule of thumb that I would recommend is:
In a header file, #include nothing, or as close to nothing as is
possible.
Why? There are at least two reasons.
First, it keeps compiles fast. This is nice, but not the real reason. The real reason is:
Second, it reduces interdependence between modules and hard couplings. An interdependence between modules is an easy thing to create, and a very difficult thing to break when it becomes a problem.
Contrary to the other answers posted here, no, you do not need to #include OtherClass's header file in this header file. This assertion yields two questions:
How is it possible to not include the header?
Why would you not include the header, even if it is possible not to?
In order:
The header file doesn't need to know anything about the definition of OtherClass. Only the translation unit does. The TU needs to know the definition of OtherClass before it can define MyClass1, but that is handled simply. Consider:
OtherClass.h:
#ifndef OTHERCLASS_H
#define OTHERCLASS_H
class OtherClass
{
};
#endif
MyClass.h:
#ifndef MYCLASS_H
#define MYCLASS_H
class MyClass
{
public:
OtherClass mOC;
};
#endif
main.cpp:
#include <cstdlib>
#include "OtherClass.h"
#include "MyClass.h"
int main()
{
MyClass mc;
}
The Translation Unit here is main.cpp and everything it #includes. The whole package. Since you do not compile header files directly (eg by themselves), headers are not translation units.
I suggest that what I propose above is better than adding:
#include "OtherClass.h"
to MyClass.h because it reduces the interdependence between the two objects.
This obviously isn't a concern right now, or in a toy program such as this. It becomes an issue later, in large & complicated codebases when you try to make changes to underlying classes. At those times, breaking these interdependancies becomes exceedingly difficult and maybe impossible depending on how much forethought you have given your design. This becomes a lesson learned with great difficulty.
Yes. If oc was a pointer or a reference, then you could get by with just a forward declaration (which appears above the class statement):
class OtherClass;
class myClass1 {
...
The include statement is needed because the compiler needs to know the details of OtherClass to define myClass1.
Yes include using #include "OtherClass.h". If you were using a system header or maybe something from STL, you would use: #include <SomeSystemHeader>
I'm pretty clear on when I can/can't use forward declaration but I'm still not sure about one thing.
Let's say I know that I have to include a header sooner or later to de-reference an object of class A.
I'm not clear on whether it's more efficient to do something like..
class A;
class B
{
A* a;
void DoSomethingWithA();
};
and then in the cpp have something like..
#include "A.hpp"
void B::DoSomethingWithA()
{
a->FunctionOfA();
}
Or might I as well just include A's header in B's header file in the first place?
If the former is more efficient then I'd appreciate it if someone clearly explained why as I suspect it has something to do with the compilation process which I could always do with learning more about.
Use forward declarations (as in your example) whenever possible. This reduces compile times, but more importantly minimizes header and library dependencies for code that doesn't need to know and doesn't care for implementation details. In general, no code other than the actual implementation should care about implementation details.
Here is Google's rationale on this: Header File Dependencies
When you use forward declaration, you explicitly say with it "class B doesn't need to know anything about internal implementation of class A, it only needs to know that class named A exists". If you can avoid including that header, then avoid it. - it's good practice to use forward declaration instead because you eliminate redundant dependencies by using it.
Also note, that when you change the header file, it causes all files that include it to be recompiled.
These questions will also help you:
What are the drawbacks of forward declaration?
What is the purpose of forward declaration?
Don't try to make your compilation efficient. There be dragons. Just include A.hpp in B.hpp.
The standard practice for C and C++ header files is to wrap all of the header file in an #ifndef to make sure it is compiled only once:
#ifndef _A_HPP_
#define _A_HPP_
// all your definitions
#endif
That way, if you #include "A.hpp" in B.hpp, you can have a program that includes both, and it won't break because it won't try to define anything twice.
I have a question regarding "best-practice" when including headers.
Obviously include guards protect us from having multiple includes in a header or source file, so my question is whether you find it beneficial to #include all of the needed headers in a header or source file, even if one of the headers included already contains one of the other includes. The reasoning for this would be so that the reader could see everything needed for the file, rather than hunting through other headers.
Ex: Assume include guards are used:
// Header titled foo.h
#include "blah.h"
//....
.
// Header titled bar.h that needs blah.h and foo.h
#include "foo.h"
#include "blah.h" // Unnecessary, but tells reader that bar needs blah
Also, if a header is not needed in the header file, but is needed in it's related source file, do you put it in the header or the source?
In your example, yes, bar.h should #include blah.h. That way if someone modifies foo so that it doesn't need blah, the change won't break bar.
If blah.h is needed in foo.c but not in foo.h, then it should not be #included in foo.h. Many other files may #include foo.h, and more files may #include them. If you #include blah.h in foo.h, then you make all those files needlessly dependent on blah.h. Needless dependencies cause lots of headaches:
If you modify blah.h, all those files must be recompiled.
If you want to isolate one of them (say, to carry it over to another project or build a unit test around it) you have to take blah.h along.
If there's a bug in one of them, you can't rule out blah.h as the cause until you check.
If you are foolish enough to have something like a macro in blah.h... well, never mind, in that case there's no hope for you.
The basic rule is, #include any headers that you actually use in your code. So, if we're talking:
// foo.h
#include "utilities.h"
using util::foobar;
void func() {
foobar();
}
// bar.h
#include "foo.h"
#include "utilities.h"
using util::florg;
int main() {
florg();
func();
}
Where bar.h uses tools from the header included twice, then you should #include it, even if you don't necessarily have to. On the other hand, if bar.h doesn't need any functions from utilities.h, then even though foo.h includes it, don't #include it.
The header for a source file should define the interface that the users of the code need to use it accurately. It should contain all that they need to use the interface, but nothing extra. If they need the facility provided by xyz.cpp, then all that is required by the user is #include "xyz.h".
How 'xyz.h' provides that functionality is largely up to the implementer of 'xyz.h'. If it requires facilities that can only be specified by including a specific header, then 'xyz.h' should include that other header. If it can avoid including a specific header (by forward definition or any other clean means), it should do so.
In the example, my coding would probably depend on whether the 'foo.h' header was under the control of the same project as the 'blah.h' header. If so, then I probably would not make the explicit second include; if not, I might include it. However, the statements above should be forcing me to say "yes, include 'foo.h' just in case".
In my defense, I believe the C++ standard allows the inclusion of any one of the C++ headers to include others - as required by the implementation; this could be regarded as similar. The problem is that if you include just 'bar.h' and yet use features from 'blah.h', then when 'bar.h' is modified because its code no longer needs 'blah.h', then the user's code that used to compile (by accident) now fails.
However, if the user was accessing 'blah.h' facilities directly, then the user should have included 'blah.h' directly. The revised interface to the code in 'bar.h' does not need 'blah.h' any more, so any code that was using just the interface to 'bar.h' should be fine still. But if the code was using 'blah.h' too, then it should have been including it directly.
I suspect the Law of Demeter also should be considered - or could be viewed as influencing this. Basically, 'bar.h' should include the headers that are needed to make it work, whether directly or indirectly - and the consumers of 'bar.h' should not need to worry much about it.
To answer the last question: clearly, headers needed by the implementation but not needed by the interface should only be included in the implementation source code and absolutely not in the header. What the implementation uses is irrelevant to the user and compilation efficiency and information hiding both demand that the header only expose the minimum necessary information to the users of the header.
Including everything upfront in headers in C++ can cause compile times to explode
Better to encapsulate and forward declare as much as possible. The forward declarations provide enough hints to what is required to use the class. Its quite acceptable to have standard includes in there though (especially templates as they cannot be forward declared).
My comments might not be a direct answer to your question but useful.
IOD/IOP encourages that put less headers in INTERFACE headers as possible, the main benefits to do so:
less dependencies;
smaller link-time symbols scope;
faster compiling;
smaller size of final executables if header contains static C-style function definitions etc.
per IOD/IOP, should interfaces only be put in .h/.hxx headers. include headers in your .c/.cpp instead.
My Rules for header files are:
Rule #1
In the header file only #include class's that are members or base classes of your class.
If your class has pointers or references used forward declarations.
--Plop.h
#include "Base.h"
#include "Stop.h"
#include <string>
class Plat;
class Clone;
class Plop: public Base
{
int x;
Stop stop;
Plat& plat;
Clone* clone;
std::string name;
};
Caviat: If your define members in the header file (example template) then you may need to include Plat and Clone (but only do so if absolutely required).
Rule #2
In the source put header files from most specific to least specific order.
But don't include anything you do not explicitly need too.
So in this case you will inlcude:
Plop.h (The most specific).
Clone.h/Plat.h (Used directly in the class)
C++ header files (Clone and Plat may depend on these)
C header files
The argument here is that if Clone.h needs map (and Plop needs map) and you put the C++ header files closer to the top of the list then you hide the fact that Clone.h needs map thus you may not add it inside Clone.h.
Rule #3
Always use header guards
#ifndef <NAMESPACE1>_<NAMESPACE2>_<CLASSNAME>_H
#define <NAMESPACE1>_<NAMESPACE2>_<CLASSNAME>_H
// Stuff
#endif
PS: I am not suggesting using multiple nested namespaces. I am just demonstrating how I do if I do it. I normal put everything (apart from main) in a namespace. Nesting would depend on situation.
Rule #4
Avoid the using declaration.
Except for the current scope of the class I am working on:
-- Stop.h
#ifndef THORSANVIL_XXXXX_STOP_H
#define THORSANVIL_XXXXX_STOP_H
namespace ThorsAnvil
{
namespace XXXXX
{
class Stop
{
};
} // end namespace XXXX
} // end namespace ThorsAnvil
#endif
-- Stop.cpp
#include "Stop.h"
using namespace ThorsAnvil:XXXXX;
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.