Reputation: 2041
I'm wondering why the code bellow is not working. In b.cpp, class B uses class A, but it fails because the declaration of the class A is not found. However, a.hpp is included just before. Why the #include "a.hpp" is not working here?
Thanks for any help!
//===============================================
//file: a.hpp
//===============================================
#ifndef _A_HPP
#define _A_HPP
#include "b.hpp"
class A{
public:
A();
// others methods using B here
};
#endif
//===============================================
//file: a.cpp
//===============================================
#include "a.hpp"
A::A(){}
//===============================================
//file: b.hpp
//===============================================
#ifndef _B_HPP
#define _B_HPP
#include "a.hpp"
class B{
public:
B(A a);
};
#endif
//===============================================
//file: b.cpp
//===============================================
#include "b.hpp"
B::B(A a){}
SHELL$ g++ -c a.cpp
In file included from a.hpp:7,
from a.cpp:4:
b.hpp:11: error: expected ‘)’ before ‘a’
Upvotes: 1
Views: 295
Reputation: 1805
This won't work. In you header files you should only include references or pointers to the other class. Then you can forward declare A or B, e.g.:
//===============================================
//file: b.hpp
//===============================================
#ifndef _B_HPP
#define _B_HPP
class A;
class B{
public:
B(A& a);
};
#endif
Upvotes: 1
Reputation: 15327
In A.hpp, do not include B.hpp or inline A implementations that call B methods.
Use class B;
in A.hpp (a forward declaration) if you need to refer to B&
or B*
.
Instead, put those A implementations that call B methods in A.cpp and include B.hpp in A.cpp.
Upvotes: 0
Reputation: 5456
When b.hpp includes a.hpp, _A_HPP
is already defined, so the precompiler ignore the content of the file, so in the line B(A a)
, the compiler doesn't know about A.
if you really need these includes, try move the #include "b.hpp"
to the end of a.hpp
(or declare class A;
in the head of b.hpp
).
Upvotes: 0
Reputation: 6578
Why do you need a cyclic #include
like that? If you just need for the compiler to know a class exists (so it can be a parameter et cetera), just forward declare it like this:
class A;
Don't cyclically include files. Even with the guards, they'll both only be included once, sure, but then you're still going to run into a mention of A
before the compiler gets to its definition, or a mention of B
before the compiler gets to its definition.
Upvotes: 0
Reputation: 258568
Remove the
#include "b.hpp"
from a.h
and only have a forward declaration - assuming you use pointers to B
in A
:
//A.hpp
class B; //forward declaration
class A{
public:
A();
// others methods using B here
};
Also: Macro names starting with underscore _
are reserved by the standard and should not be used. Replace _B_HPP
with simply B_HPP
.
Upvotes: 0
Reputation: 206518
You need to use Forward declarations to break such circular dependency.
However, note that once you forward declare a type, that type becomes an Incomplete Type for the compiler and there are restrictions on how you can use the Incomplete type
Upvotes: 2