Say I have these two classes:
// a.h
#include "b.h"
and:
// b.h
include "a.h"
I understand there is a problem over here, but how can I fix it and use a objects and their methods in b class and vice versa?
You can use forward declarations, like this:
class B;
class A
{
B* ThisIsValid;
}
class B
{
A SoIsThis;
}
For more information, see this SO question.
As for the preprocessor #includes, there's likely a better way to organize your code. Without the full story, though, it's hard to say.
To extend on #Borealid 's answer:
To avoid problems with circular includes, using an "include guard"
eg.
#ifndef MYFILE_H /* If this is not defined yet, it must be the first time
we include this file */
#define MYFILE_H // Mark this file as already included
// This only works if the symbol we are defining is unique.
// code goes here
#endif
You can use what is called a "forward declaration".
For a function, this would be something like void myFunction(int);. For a variable, it might look like extern int myVariable;. For a class, class MyClass;. These bodiless statements can be included before the actual code-bearing declarations, and provide the compiler with enough information to produce code making use of the declared types.
To avoid problems with circular includes, using an "include guard" - an #ifdef at the top of each header file which prevents it being included twice.
The "other" class can only have a reference or pointer to the "first" class.
in file a.h:
#include "b.h"
struct a {
b m_b;
};
in file b.h:
struct a;
struct b {
a* m_a;
};
void using_the_a_instance(b& theb);
in file b.cpp:
#include "b.h"
#include "a.h"
void using_the_a_instance(b& theb)
{
theb.m_a = new a();
}
Related
I'm a C++ newbie, but I wasn't able to find the answer to this (most likely trivial) question online. I am having some trouble compiling some code where two classes include each other. To begin, should my #include statements go inside or outside of my macros? In practice, this hasn't seemed to matter. However, in this particular case, I am having trouble. Putting the #include statements outside of the macros causes the compiler to recurse and gives me "#include nested too deeply" errors. This seems to makes sense to me since neither class has been fully defined before #include has been invoked. However, strangely, when I try to put them inside, I am unable to declare a type of one of the classes, for it is not recognized. Here is, in essence, what I'm trying to compile:
A.h
#ifndef A_H_
#define A_H_
#include "B.h"
class A
{
private:
B b;
public:
A() : b(*this) {}
};
#endif /*A_H_*/
B.h
#ifndef B_H_
#define B_H_
#include "A.h"
class B
{
private:
A& a;
public:
B(A& a) : a(a) {}
};
#endif /*B_H_*/
main.cpp
#include "A.h"
int main()
{
A a;
}
If it makes a difference, I am using g++ 4.3.2.
And just to be clear, in general, where should #include statements go? I have always seen them go outside of the macros, but the scenario I described clearly seems to break this principle. Thanks to any helpers in advance! Please allow me to clarify my intent if I have made any silly mistakes!
By "the macros" I assume you mean the #ifndef include guards?
If so, #includes should definitely go inside. This is one of the major reasons why include guards exists, because otherwise you easily end up with an infinite recursion as you noticed.
Anyway, the problem is that at the time you use the A and B classes (inside the other class), they have not yet been declared. Look at what the code looks like after the #includes have been processed:
//#include "A.h" start
#ifndef A_H_
#define A_H_
//#include "B.h" start
#ifndef B_H_
#define B_H_
//#include "A.h" start
#ifndef A_H_ // A_H_ is already defined, so the contents of the file are skipped at this point
#endif /*A_H_*/
//#include "A.h" end
class B
{
private:
A& a;
public:
B(A& a) : a(a) {}
};
#endif /*B_H_*/
//#include "B.h" end
class A
{
private:
B b;
public:
A() : b(*this) {}
};
#endif /*A_H_*/
//#include "A.h" end
int main()
{
A a;
}
Now read the code. B is the first class the compiler encounters, and it includes an A& member. What is A? The compiler hasn't encountered any definition of A yet, so it issues an error.
The solution is to make a forward declaration of A. At some point before the definition of B, add a line class A;
This gives the compiler the necessary information, that A is a class. We don't know anything else about it yet, but since B only needs to include a reference to it, this is good enough. In the definition of A, we need a member of type B (not a reference), so here the entire definition of B has to be visible. Which it is, luckily.
And just to be clear, in general, where should #include statements go?
Inside the include guards, for the reason you mentioned.
For your other problem: you need to forward-declare at least one of the classes, e.g. like this:
#ifndef B_H_
#define B_H_
// Instead of this:
//#include "A.h"
class A;
class B
{
private:
A& a;
public:
B(A& a) : a(a) {}
};
#endif /*B_H_*/
This only works for declarations though: as soon as you really use an instance of A, you need to have defined it as well.
By the way, what Nathan says is true: you can't put class instances into each other recursively. This only works with pointers (or, in your case, references) to instances.
In such situations, i create a common header to be included in all sources with forward declarations:
#ifndef common_hpp
#define common_hpp
class A;
class B;
#endif
Then the individual class header files typically don't need any #includes to reference other classes, if all that's needed are pointers or references to those classes. Half the time though there are other goodies in those headers, but at least any problem with circular references are solved with common.hpp
Oops! I think I found a solution that involves putting the #include statements inside the class and using a forward declaration. So, the code looks like:
#ifndef A_H_
#define A_H_
class B;
#include "B.h"
class A
{
private:
B b;
public:
A() : b(*this) {}
};
#endif /*A_H_*/
And similarly for class B. It compiles, but is this the best approach?
Dependency between two classes in a good software design can be drawn as a tree.
For this reason C++ won't let two .h files #include each other.
I doubt that this can be done. You're not talking about calling two functions from inside each other recursively, but rather of putting two objects one inside the other recursively. Think about putting a house with a picture of a house with a picture of a house etc... This will take up an infinite amount of space because you'll have an infinite number of houses and pictures.
What you can do is have each of A and B include either pointers or references to each other.
Some compilers (inc. gcc) also support #pragma once however the 'include guards' idiom in your question is the usual practice.
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 circular header problem that is different from most of the ones already asked on here. I have two classes that depend on each other but not as members so don't run into the problem of the compiler not being able to calculate the class's sizes. So I'm able to use a forward-declaration to break the cycle.
However, I don't want the client to have to include both these headers to use my classes. The headers should be self-contained so the user doesn't need to be aware of this dependency. Is there some way to do this?
Edit: the tricky part is that A and B must be defined header-only.
In header A.hpp
#ifndef A_HPP
#define A_HPP
#include "B.hpp"
struct A
{
B foo() { ... }
};
#endif
In header B.hpp
#ifndef B_HPP
#define B_HPP
struct A;
struct B
{
void bar()
{
A a = A();
...
}
};
#endif
In main.cpp
#include "B.hpp"
B().bar(); // error: 'a' uses undefined class 'A'
Header B.hpp
#ifndef B_HPP
#define B_HPP
struct A;
struct B
{
void bar();
};
#endif
Source B.cpp
#include "A.hpp"
void B::bar()
{
A a;
}
EDIT. So, if you want header-only implementation, then use AndreyT solution.
If both headers contain code that requires the other type to be complete, then in general case it cannot possibly be implemented by self-contained headers.
In your specific example (which is too simple to be representative), you can simply move the definition if B::bar to A.hpp:
inline void B::bar()
{
A a = A();
...
}
But, of course, having methods of B defined in A.hpp doesn't look very elegant.
If the "inlinedness" of B::bar is important to you, the "industrial" solution would involve placing the definition of B::bar into an additional header file B_aux.hpp. When you include the headers, you should include the "aux" ones after all "normal" ones are included, i.e. in main.cpp you'd have
#include "A.hpp"
#include "B.hpp"
#include "C.hpp"
...
#include "B_aux.hpp"
...
But this is, obviously, not a "self-contained" approach.
Just add a #include "A.hpp" to the bottom of B.hpp. You'll still have a circular include, but now it won't hurt anything.
Usually circular includes are a sign that the two types are closely related, and that could mean that they are a single component. If that is the case, then just merge the two headers into a single header for the component, with the type declarations first and the member function definitions at the end, when both types have been fully defined.
I'm a C++ newbie, but I wasn't able to find the answer to this (most likely trivial) question online. I am having some trouble compiling some code where two classes include each other. To begin, should my #include statements go inside or outside of my macros? In practice, this hasn't seemed to matter. However, in this particular case, I am having trouble. Putting the #include statements outside of the macros causes the compiler to recurse and gives me "#include nested too deeply" errors. This seems to makes sense to me since neither class has been fully defined before #include has been invoked. However, strangely, when I try to put them inside, I am unable to declare a type of one of the classes, for it is not recognized. Here is, in essence, what I'm trying to compile:
A.h
#ifndef A_H_
#define A_H_
#include "B.h"
class A
{
private:
B b;
public:
A() : b(*this) {}
};
#endif /*A_H_*/
B.h
#ifndef B_H_
#define B_H_
#include "A.h"
class B
{
private:
A& a;
public:
B(A& a) : a(a) {}
};
#endif /*B_H_*/
main.cpp
#include "A.h"
int main()
{
A a;
}
If it makes a difference, I am using g++ 4.3.2.
And just to be clear, in general, where should #include statements go? I have always seen them go outside of the macros, but the scenario I described clearly seems to break this principle. Thanks to any helpers in advance! Please allow me to clarify my intent if I have made any silly mistakes!
By "the macros" I assume you mean the #ifndef include guards?
If so, #includes should definitely go inside. This is one of the major reasons why include guards exists, because otherwise you easily end up with an infinite recursion as you noticed.
Anyway, the problem is that at the time you use the A and B classes (inside the other class), they have not yet been declared. Look at what the code looks like after the #includes have been processed:
//#include "A.h" start
#ifndef A_H_
#define A_H_
//#include "B.h" start
#ifndef B_H_
#define B_H_
//#include "A.h" start
#ifndef A_H_ // A_H_ is already defined, so the contents of the file are skipped at this point
#endif /*A_H_*/
//#include "A.h" end
class B
{
private:
A& a;
public:
B(A& a) : a(a) {}
};
#endif /*B_H_*/
//#include "B.h" end
class A
{
private:
B b;
public:
A() : b(*this) {}
};
#endif /*A_H_*/
//#include "A.h" end
int main()
{
A a;
}
Now read the code. B is the first class the compiler encounters, and it includes an A& member. What is A? The compiler hasn't encountered any definition of A yet, so it issues an error.
The solution is to make a forward declaration of A. At some point before the definition of B, add a line class A;
This gives the compiler the necessary information, that A is a class. We don't know anything else about it yet, but since B only needs to include a reference to it, this is good enough. In the definition of A, we need a member of type B (not a reference), so here the entire definition of B has to be visible. Which it is, luckily.
And just to be clear, in general, where should #include statements go?
Inside the include guards, for the reason you mentioned.
For your other problem: you need to forward-declare at least one of the classes, e.g. like this:
#ifndef B_H_
#define B_H_
// Instead of this:
//#include "A.h"
class A;
class B
{
private:
A& a;
public:
B(A& a) : a(a) {}
};
#endif /*B_H_*/
This only works for declarations though: as soon as you really use an instance of A, you need to have defined it as well.
By the way, what Nathan says is true: you can't put class instances into each other recursively. This only works with pointers (or, in your case, references) to instances.
In such situations, i create a common header to be included in all sources with forward declarations:
#ifndef common_hpp
#define common_hpp
class A;
class B;
#endif
Then the individual class header files typically don't need any #includes to reference other classes, if all that's needed are pointers or references to those classes. Half the time though there are other goodies in those headers, but at least any problem with circular references are solved with common.hpp
Oops! I think I found a solution that involves putting the #include statements inside the class and using a forward declaration. So, the code looks like:
#ifndef A_H_
#define A_H_
class B;
#include "B.h"
class A
{
private:
B b;
public:
A() : b(*this) {}
};
#endif /*A_H_*/
And similarly for class B. It compiles, but is this the best approach?
Dependency between two classes in a good software design can be drawn as a tree.
For this reason C++ won't let two .h files #include each other.
I doubt that this can be done. You're not talking about calling two functions from inside each other recursively, but rather of putting two objects one inside the other recursively. Think about putting a house with a picture of a house with a picture of a house etc... This will take up an infinite amount of space because you'll have an infinite number of houses and pictures.
What you can do is have each of A and B include either pointers or references to each other.
Some compilers (inc. gcc) also support #pragma once however the 'include guards' idiom in your question is the usual practice.