I have code structure like this:
resource.h:
#include"a.h"
#include"b.h"
#include"c.h"
a.h:
#ifndef __A__
#define __A__
#include"resource.h"
class B;
class A{
//something uses B
};
#endif
b.h:
#ifndef __B__
#define __B__
#include"resource.h"
class A;
class B{
//something uses A
}
#endif
c.h:
#ifndef __C__
#define __C__
#include"resource.h"
class A;
class B;
class C{
//something uses A and B
};
#endif
The problem is the following: VS2010 tells me that in c.h, line #include"resource.h" causes "resource.h" includes itself.
However, the codes are able to compile and performed as expected. So I am wondering what causes this error intellisense in VS and if there is anyway to remove it.
P.S: I am compiling with VS and there is no compiling error.
You don't have a header guard on resource.h:
#ifndef __RESOURCE__
#define __RESOURCE__ 1
#include "a.h"
#include "b.h"
#include "c.h"
#endif
However, double underscores aren't recommended, as they're reserved for the implementation. So I would use {PROJECTNAME}_RESOURCE_H. This will also prevent header guard collisions with other projects that don't do this.
Seeing that you're using Visial Studio, I would reccomend you don't use header guards and instead use #pragma once if your project isn't going I be compiled with gcc.
You can use #pragma once preprocessor to make resource.h to be included only once in compilation.
c.h includes resource.h which then itself includes a.h and b.h which each include resource.h again.
You are creating cyclic dependency.
in resource.h you have included a.h , b.h and c.h which is not required.
class files needs resource, resource file does not need class information.
Related
I am having problems with a circular dependency in a head-only library for C++ that would have not been a circular dependency problem when using source files instead of making everything header-only.
The situation is equal to this:
There are four files for two classes A and B. Every class has got its header file (e.g. "A.hpp") and its implementation file (e.g. "A.tpp").
The dependencies are as follows:
A's header requires B' header
A's impl requires B's header
B's header requires nothing but a forward declaration to A
B's impl requires A's header
So in a source-based library everything would be fine with the following order of source file inclusion and compilation:
B.hpp
A.hpp
A.tpp or B.tpp (order here is not important)
My files are structured in this way:
File content for A.hpp:
#ifndef A_H
#define A_H
#include "B.hpp"
class A { ... };
#include "A.tpp"
#endif
File content for A.tpp:
#ifndef A_H
#error "Do not include this file directly."
#endif
// ... some implementations for A.hpp
File content for B.hpp:
#ifndef B_H
#define B_H
class A;
class B { ... };
#include "B.tpp"
#endif
File content for B.tpp:
#include "A.hpp"
#ifndef B_H
#error "Do not include this file directly."
#endif
// ... some implementations for B.hpp
So my question is: Is there a solution for breaking this unnessesary circular dependency which only happens due to the fact that I am using a header-only solution for my library?
This question already has answers here:
The use of double include guards in C++
(5 answers)
Closed 5 years ago.
Ok, may be this question have answer already but I don't know what keyword to search (most of my searched results are about include guard in .h only, but not in .cpp)
Sometimes I saw in cpp each #include line have a extra include guard (sometimes even the included .h already have the own include guard) like this:
SomeClass.cpp
#ifndef__A__
#include A.h
#endif
#ifndef__B__
#include B.h
#endif
#ifndef__C__
#include C.h
#endif
instead of
SomeClass.cpp
#include A.h
#include B.h
#include C.h
, what is the function of this include guard?
The practice of using include guards in .cpp files was recommended by John Lakos in his book Large-Scale C++ Software Design. I don't know whether any one before him had recommended the practice.
Say you have
A.h:
#ifndef __A__
#define __A__
#include "B.h"
#include "C.h"
// ...
// ...
// ...
#endif
B.h:
#ifndef __B__
#define __B__
// ...
// ...
// ...
#endif
C.h:
#ifndef __C__
#define __C__
// ...
// ...
// ...
#endif
SomeClass.cpp:
#ifndef __A__
#include "A.h"
#endif
#ifndef __B__
#include "B.h"
#endif
#ifndef __C__
#include "C.h"
#endif
When SomeClass.cpp is compiled, the contents of A.h is included. As a by-product of including the contents of A.h, the contents of B.h and C.h are also included. Also, the pre-processor macros __A__, __B__ and __C__ are defined. When the line
#ifndef __B__
is processed, since __B__ is already defined, the next line is skipped.
If SomeClass.cpp had just:
#include "A.h"
#include "B.h"
#include "C.h"
the file B.h has to be opened and processed. The contents of the file will not be included again due to the include guards but the file has to be opened and closed.
By using the first strategy, you avoid the cost of of opening and closing B.h and C.h. For large scale C++ project, John Lakos asserts, the cost is too much. Hence, the recommendation of using include guards even in .cpp files.
It means don't even check the content of header file if the file is already included (symbol_specific_to_header is defined).
In ancient time when opening a file and checking whether contents are already included in header itself was costly (Cost of opening, reading and closing the header was very high) this trick was used to reduce the compile time.
But on modern systems this trick is not required. Though this doesn't cause any harm except the code is repeated and adding cluttering, this would work. Althout adding hashguards in include files is recommended.
This is how the header file looks and are included.
New style:
/* A.h */
#pragma once
...
or
/* A.h */
#ifndef A_H
#define A_H
...
#endif
usage:
#include "A.h"
Or precompiled headers are used.
Old style
The ancient style as mentioned by you:
/* A.h */
#define A_H
...
usage:
#ifndef A_H
#include "A.h"
#endif
It's to protect against including the same header twice.
A.h might look something like this
#define __A__
#include B.h
Without the guards, B.h would be included twice, which could cause errors. So the #ifndef lines in the cpp is just protecting itself from headers including other headers.
If every header uses #ifndef does this mean compiler errors regarding a circular dependency will not happen?
No, it does not.
It means the compiler won't try to include headers for infinity, but a circular dependency still poses a logical problem, because compilation is performed from top to bottom. Let's take a little look at why:
Source code
a.h
#ifndef A_H
#define A_H
#include "b.h"
struct A
{
B* ptr;
};
#endif
b.h
#ifndef B_H
#define B_H
#include "a.h"
struct B
{
A* ptr;
};
#endif
main.cpp
#include "a.h"
int main()
{
A a;
}
After preprocessor runs
The include guards enable us to actually run the preprocessor and have it finish its work in less-than-infinity time; so fast, actually, that I've done it by hand below. The result is:
struct B
{
A* ptr;
};
struct A
{
B* ptr;
};
int main()
{
A a;
}
The definition of B comes before the definition of A, so that A* ptr; cannot be understood. Sure, you can fix that, but only by reversing the order of inclusion, and then you have the opposite problem. Forward declarations and/or re-architecture are the only ways to resolve it.
Header guards solve a different problem. They do not allow you to simply do whatever you like.
It will not create any circular dependency, it will include the file multiple times as the name 'include' says. This usually happens when the code base is big and the we dont know if this file is already included by another header file.
We can also use a single statement , #pragma once
Why declare the class that you included as a header file?
#include "TreeCallObj.h"
#include "TreeDevObj.h"
#include "TreeDevCallObj.h"
class TreeCallObj; //what is the purpose of this line ?
class TreeDevObj; //what is the purpose of this line ?
class TreeDevCallObj; //what is the purpose of this line ?
class Apple
{
public:
...
private:
...
}
Consider this:
//a.h
#ifndef A_H
#define A_H
#include "b.h"
class A
{
B* b;
};
#endif
//b.h
#ifndef B_H
#define B_H
#include "a.h"
class B
{
A* a;
};
#endif
Now you try to include one of the files in a different one, say you #include "a.h".
The compiler will parse it as:
#ifndef A_H
#define A_H
fine - A_H isn't defined
#include "b.h"
try to paste the contents:
#ifndef B_H
#define B_H
ok, since B_H isn't defined
#include "a.h"
this will not define A, because A_H is defined. So next, we have
class B
{
A* a;
};
which will lead to an error, because A wasn't defined or declared before the use.
The forward declaration fixes this.
Of course, the best solution to this is to not include at all (unless you absolutely have to).
What is the purpose of this line?
Ideally nothing. It's superfluous.
However, as #Luchian Grigore pointed out, there may be such a badly-designed code that due to the incorrect use of include guards and cross-includes, the forward declarations may be necessary.
If in files there is definition of classes, so, forward declaration is unnecessary in normal cases.
No reason at all. You need to do one or the other, depending on the situation, but not both.
As it stands, there's no need.
However, this may have evolved historically: At some point, an incomplete type may have been enough:
class Foo;
struct Gizmo
{
void f(Foo);
};
Then, at a later point, the author decided she needed the complete type:
#include "Foo.hpp"
class Foo;
struct Gizmo
{
void f(Foo);
Foo x;
};
The original code may just have been amended with the now-necessary header inclusion...
I would guess there's some history to this. Orginally the coder tried not to include the header files and used forward declarations instead. Then as the code expanded they found they needed the header files after all, but didn't bother to deleted the forward declarations.
As others have said there's no purpose to having a forward declaration after the class declaration.
I notice that your header does not have guards against multiple inclusion. Also it is possible that some of the included other headers (headers usually have such guards) included that header back. As result it did not compile. So someone added forward declarations to fix the wrong bug.
If your header files are correct i see no point in declaring because they should already declared in header
I have a number of classes and they are quite close to each other like
class A
{
//code
};
class B
{
A* field;
//code
};
class C: public B
{
//code
};
And so on.
And I want to place them in a separate headers (A.h, B.h...) but to avoid adding every one of this header to projects I need a header like myLib.h, that will be just one needed header to include all the classes that I have wrote. Ho do I achieve it?
Also I think not to use #pragma once; and to make it working
#ifndef _MY_LIB_H
#define _MY_LIB_H
#endif
Where should I place it? In every header?
I've tried doing it like
class A;
class B;
...
in myLib.h
but then adding myLib.h to main.cpp is not enough to use A or B objects there. Also, in B.h that
#inlude myLib.h
void someMethod()
{
//field is instance of A
this.field.otherMethod();
}
causes an error because methods of A are declared in A.h, not in myLib.h.
Sorry for long and tangled question.
You should use a separate include guard in each of A.h, B.h, C.h:
// Note: not a good name for a guard macro (too short)
#ifndef _A_H
#define _A_H
// definition of A
#endif
And then MyLib.h becomes simply:
#include<A.h>
#include<B.h>
#include<C.h>
Of course each of your headers should manually include as many of the others as required so that it can stand alone (e.g. C.h would need to include B.h so that the code compiles if someone includes C.h directly).
In some cases you will not need to have one header include another because a forward declaration is enough -- for example in B.h, where an A* member is declared:
#ifndef _B_H
#define _B_H
class A;
class B
{
A* field;
};
#endif
Besides using the pattern
#ifndef _A_H
#define _A_H
... Stuffs
#endif
in each header, I always add
#ifndef _A_H
#include <A.h>
#endif
#ifndef _B_H
#include <B.h>
#endif
....
to other headers, like myLib.h. This considerably improves the speed of compilation because compiler does not need to load and scan the low level headers if they are already scanned.
I do not add this to my cpp files, because the number of headers in cpp is typically reasonable, while it mich more difficult to track relations between headers.