Proper way to #include when there is a circular dependency? - c++

I'm using #pragma once, not #include guards on all my h files. What do I do if a.h needs to #include b.h and b.h needs to #include a.h?
I'm getting all sorts if errors because by doing this, the pragma once takes effect and one of them is missing each other. How should I do this.
Thanks

You need to forward declare the definitions you need. So if A uses B as a parameter value, you need to forward declare B, and vice versa.
It could be that just forward declaring the class names:
class A;
class B;
solves your problems.
The accepted answer to this question provides some additional guidance.

One possibility is to refactor some portion of the files a.h and b.h into a third file say c.h, and include it from both a.h and b.h. This way, the latter two would no longer need to mutually include each other.
Another possibility is to merge the separate header files into one.
A third possibility is the situation when two classes legitimately need to refer to each other. In such cases you have to use pointers. Moreover, you can forward declare the class instead of including its header file. [Mentioned also by jdv] For example,
// file a.h
struct B;
struct A { B * b_ };
// file b.h
struct A;
struct B { A * a_; };
However, without knowing your particular situation it is difficult to provide specific suggestion.

It depends on what is needed from each other's header file. IF it's a class definition, but it only is using a pointer to the class, then instead of including the head file just put in a forward declaration like:
class MyClassA;

The solution for this issue is 'forward declaration'.
If you have a class or a function that needs to be used in 2 headers one of the headers needs to forward declare the used class or type.
Or you need to consider to restructure your headers.
This is a common beginner issue that circular dependencies are causing such issues. If you google on 'forward declaration' will find tons of results.
Since your question was too unspecific I can't give you an exact answer, sorry for this.

You can not use incomplete types, but you can just forward declare them. You just tell the compiler:"Don't get syntax errors, I know what i am doing". Which means that the linker will go and find complete types from libraries whatsoever.

Related

Header Include Creep in C++

When I started learning C++ I learned that header files should typically be #included in other header files. Just now I had someone tell me that I should include a specific header file in my .cpp file to avoid header include creep.
Could someone tell me what exactly that is, why it is a problem and maybe point me to some documentation on when I would want to include a file in another header and when I should include one in a .cpp file?
The "creep" refers to the inclusion of one header including many others. This has some unwanted consequences:
a tendency towards every source file indirectly including every header, so that a change to any header requires everything to be recompiled;
more likelihood of circular dependencies causing heartache.
You can often avoid including one header from another by just declaring the classes you need, rather than including the header that gives the complete definition. Such an incomplete type can be used in various ways:
// Don't need this
//#include "thingy.h"
// just this
class thingy;
class whatsit {
// You can declare pointers and references
thingy * p;
thingy & r;
// You can declare static member variables (and external globals)
// They will need the header in the source file that defines them
static thingy s;
// You can declare (but not define) functions with incomplete
// parameter or return types
thingy f(thingy);
};
Some things do require the complete definition:
// Do need this
#include "thingy.h"
// Needed for inheritance
class whatsit : thingy {
// Needed for non-static member variables
thingy t;
// Needed to do many things like copying, accessing members, etc
thingy f() {return t;}
};
Could someone tell me what exactly [include creep] is
It's not a programming term, but interpreting it in an Engish-language context would imply that it's the introduction of #include statements that are not necessary.
why it is a problem
Because compiling code takes time. So compiling code that's not necessary takes unnecessary time.
and maybe point me to some documentation on when I would want to include a file in another header and when I should include one in a .cpp file?
If your header requires the definition of a type, you will need to include the header that defines that type.
#include "type.h"
struct TypeHolder
{
Type t;
// ^^^^ this value type requires the definition to know its size.
}
If your header only requires the declaration of a type, the definition is unnecessary, and so is the include.
class Type;
struct TypeHolder
{
Type * t;
// ^^^^^^ this pointer type has the already-known size of a pointer,
// so the definition is not required.
}
As an anecdote that supports the value of this practice, I was once put on a project whose codebase required ONE HOUR to fully compile. And changing a header often incurred most or all of that hour for the next compilation.
Adding forward-declarations to the headers where applicable instead of includes immediately reduced full compilation time to 16 minutes, and changing a header often didn't require a full rebuild.
Well they were probably referring to a couple of things ("include creep" is not a term I've ever heard before). If you, as an extreme rule, only include headers from headers (aside from one matching header per source file):
Compilation time increases as many headers must be compiled for all source files.
Unnecessary dependencies increase, e.g. with a dependency based build system, modifying one header may cause unnecessary recompilation of many other files, increasing compile time.
Increased possibility of namespace pollution.
Circular dependencies become an issue (two headers that need to include each other).
Other more advanced dependency-related topics (for example, this defeats the purpose of opaque pointers, which causes many design issues in certain types of applications).
As a general rule of thumb, include the bare minimum number of things from a header required to compile only the code in that header (that is, enough to allow the header to compile if it is included by itself, but no more than that). This will combat all of the above issues.
For example, if you have a source file for a class that uses std::list in the code, but the class itself has no members or function parameters that use std::list, there's no reason to #include <list> from the class's header, as nothing in the class's header uses std::list. Do it from the source file, where you actually need it, instead of in the header, where everything that uses the class also has to compile <list> unnecessarily.
Another common technique is forward declaring pointer types. This is the only real way to combat circular dependency issues, and has some of the compilation time benefits listed above as well. For example, if two classes refer to each other but only via pointers:
// A.h
class B; // forward declaration instead of #include "B.h"
class A {
B *b;
}
// B.h
class A; // forward declaration instead of #include "A.h"
class B {
A *a;
}
Then include the headers for each in the source files, where the definitions are actually needed.
Your header files should include all headers they need to compile when included alone (or first) in a source file. You may in many cases allow the header to compile by using forward declarations, but you should never rely on someone including a specific header before they include yours.
theres compie time to think of, but there's also dependancies. if A.h includes B.h and viceversa, code won't compile. You can get around this by forward referancing your class, then including the header in the cpp
A.h
class B;
class A
{
public:
void CreateNewB():
private:
B* m_b;
};
A.cpp
#include "B.h"
A::CreateNewB()
{
m_b = new B;
}

Forward declaration for member pointer with public access

Somewhat similar situation to what was asked here.
I've got a class A that has a member pointer to class B.
//A.h
class B;
class A {
B *b;
public:
B *GetB();
};
B is defined in its own file.
Now, whenever I include A.h and want to access an A's b member, I also have to include B.h. In the case where both A and B have rather large headers (think old nasty legacy code) is it better to continue including both headers whenever I include one or to just have A.h include B.h and be done with it?
The headers are pretty large but most of our code requires both anyway, I'm just curious if there is some kind of design pattern that decides what is the best decision to make in this case.
This is opinion, of course. For me, it boils down to whether it makes sense to use A without B. If A has a ton of operations and only one of them involves B, then no, I wouldn't include B.h. Why should someone who only calls A.Foo() and A.Bar() need to pay the overhead of including an extra header?
On the other hand, if A is a B factory (for example) and you can't imagine anyone using it and not using B too, then maybe it makes sense to include B.h in A.h.
And if A had a member variable of type B (not B*) with the consequence that anyone who included A.h would have to include B.h too in order to compile, then I would definitely include it in A.h.
wrap your header files with preprocessor to make sure they will be included only 1 time..
on B.h define
#ifndef __B_HEADER__
#define __B_HEADER__
.... B header files goes here....
#endif
then on A.h define
#ifndef __A_HEADER__
#define __A_HEADER__
#include <B.h>
.... A header files goes here....
#endif
and then include only A.h when it needs.
i personally prefer to include header files of what i know and want to use - i don't want to be bothered by the dependendcy tree of the components i use.
think when you include <iostream> in C++ STD library - do you really want to know and include explicitly all the <iostrem> dependencies (if there are)?

Forward declaration / when best to include headers?

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.

Should I include files included in another header?

Most often when creating multiple classes inside a program that use each other, I like to include only the minimum number of header files I need to reduce clutter.
For example, say class C inherits from class B, which contains class A. Now of course since class B contains class A as a member, it needs to include a.h in b.h. However, let's say C also needs to include a.h. Being lazy as I am, I just include b.h (which C needs to include anyways), and since b.h already includes a.h, I don't need to include anything more, and it compiles fine. Same for my .cpp files: I just include the header, and anything that's included in the header will be automatically included in my .cpp file, so I don't include it there.
Is this a bad habit of mine? Does it make my code less readable?
I stick with this simple rule: include everything you need to completely declare a given class, but not more and make no assumptions about includes being pulled in from other sources, i.e. ensure your files are self-sufficient.
Include what's necessary for the header file to be parsed without relying on external include ordering (in other words : make your headers self-sufficient).
In your case, if c.h declares a class C which inherits from class B, obviously you must include B.h. However, if class A never appears in c.h, I believe there is no reason to include it. The fact that b.h mentions A means that b.h must make what's necessary to be parsed, either through forward declaring A or including a.h.
So from my point of view, you're doing what should be done.
Also note that if for some reasons c.h starts mentioning A, I would add the appropriate include or forward declaration so I wouldn't depend on the fact that b.h does it for me.
It's best to include every header with definitions that you are using directly.
Relying on one of the other headers to include stuff makes your code more fragile as it becomes dependent on the implementation of classes that are external to it.
EDIT:
A short example:
Class B uses class A, e.g. a hash table implementation B that uses a hashing mechanism A
You create a class C that needs a hash table (i.e. B) and a hash algorithm (i.e. A) for some other purpose. You include B.h and leave out A.h since B.h includes it anyway.
Mary, one of your co-workers, discovers a paper about this new fabulous hashing algorithm that reduces the probability of collisions, while it needs 10% less space and is twice as fast. She (rightly) rewrites class B to use class D, which implements that algorithm. Since class A is no longer needed in B, she also removes all references to it from B.h.
Your code breaks.
EDIT 2:
There are some programmers (and I've occasionally been guilty of this too, when in a hurry) who deal with this issue by having an "include-all" header file in their project. This should be avoided, since it causes namespace pollution of unparalleled proportions. And yes, windows.h in MSVC is one of those cases in my opinion.

forward declaration of class

In A.h I have the following class
class A
{
int a;
char name[100];
}
B.h has the following code
class A;
Class B
{
public:
int c;
float d;
getObjectDetails(A *);
};
I compiled it as g++ A.h B.h B.cpp -o out. But it gives compilation errors saying class A is incomplete. Could any one please help me understand?
Also, if I include header file A.h in B.h, everything goes fine. In that case, I need not declare Class A before Class B definition I think, I can directly create and use instance of class A. Could anyone clarify me on this point?
what happens in step "class A" declaration at compile time and run time?
You can only use forward declarations
with pointers and references (because
these are of a fixed size, independent
of the size of the object they refer
to). If you use a specific class by
value, the compiler needs its full
definition (in order to know its exact
size), thus forward declaration is not
enough.
You can only use forward declarations
for type identification, such as when
you use the declared type in a
function/method pointer parameter
prototype. If you are going to declare
a member variable (i.e. std::string
_name;) the compiler needs a little bit more than a forward declaration
can give it. For example, if someone
does a sizeof(Student) the compiler
has to have access to the entire
declaration to figure out the size.
Answer by Péter Török from this thread.
It should compile fine, if you
1) add a semi-colon at the end of class A declaration.
2) change "C" to "c" in class B declaration.
3) add a return type to getObjectDetails()
The problem is surely in B.cpp, because B.h is fine. If you are trying to do anything with the A* received by getObjectDetails() (such as calling a method on it), the compiler will not be able to understand it.
To fix it, try including A.h in B.cpp (B.h does not need it, indeed).
You probably don't have #include "A.h" in B.cpp, which is then using A in such a way that it requires A to be defined, not just declared. Absent the definition, just about the only thing you can do with the A* passed to getObjectDetails is store it in an A* or void* variable, or pass it on to some other code outside B.cpp.
You should #include A.h from B.h. What you've done instead is called a forward declaration, and is only recommended when A.h either contains an enormous amount of code, or includes other files that do. Then, the "class A;" thing can be a quick way to let your compiler know that A is a class, and hence accept pointers and reference to A objects, without parsing all the extra code from A.h. Your A.h is not long enough to justify such a hack. It is much better to directly use the authoratative source of information about A, which is A.h, instead of spreading information about A (which may one day cease to be true) throughout B. I actively dislike this forward declaration hack, and recommend creating a dedicated forward declaration header that contains "class A;" and any other classes A.h grows to contain, so that uses like B can include that if they don't need the full declarations. This is done by the Standard Library in , which forward declares useful classes, variables and constants for the heavier-weight .
Then, your B.cpp should #include B.h. Your command line should simply be:
g++ B.cpp -o out
(no need to mention A.h or B.h as they will be included (indirectly and directly respectively) from B.cpp.
This code
class A;
class B
{
public:
int c;
float d;
void getObjectDetails(A *);
};
compiles fine for me using VC9 (VS 2008) and I believe this to be correct.
If your code does not compile, it differs from the above in a significant detail. The only way for you to find that (there's no way for us to find it) is to take (a copy of) your original code, and start removing things step by step until the error goes away.
Either you then understand what the problem is or you end up with <20 lines of self-contained example code which reproduce the error - a perfect repro to come back here and ask about.