I've run into a simple problem that I need some help with.
I basically have two classes [A & B] (one in each .cpp file with their own .h).
A.h #includes the contents from B.h
B.h #includes the contents from A.h
I've included a header guard, yet, if I try to declare any pointers or objects of type A or B, I'm getting the following errors:
Error 1 error C2061: syntax error : identifier 'B'
Error 3 error C2143: syntax error : missing ';' before '*'
Error 4 error C4430: missing type specifier - int assumed. Note: C++
does not support default-int
Any way around it? The declarations are there - I just don't know why it won't accept it.
If you only require pointers, you only need a forward declaration. Instead of including the headers in each other, simply forward declare the class you need a pointer to. For example, in A.h, you should have:
class B;
And vice versa in B.h.
The reason you're currently having problems is because A.h has a B* in it, so it includes B.h, and B.h has a A*, so it includes A.h. However, the include guard prevents the contents of A.h being included again, so B can't compile.
Let's take a simple example. Here's A.h:
#ifndef A_H
#define A_H
#include "B.h"
class A {
B* b;
};
#endif
Here's B.h:
#ifndef B_H
#define B_H
#include "A.h"
class B {
A* a;
};
#endif
So let's say we're compiling A.h. First we check the inclusion guard, which passes. Then we include B.h, which also has an inclusion guard that passes, so lets show that inclusion:
#include "A.h"
class B {
A* a;
};
class A {
B* b;
};
Now this B.h includes A.h, but the include guard in A.h won't pass again, so the include brings nothing in. Our final preprocessed file looks like:
class B {
A* a;
};
class A {
B* b;
};
Now look at the definition of B. It has an A* in it, but A hasn't yet been declared. This gives you an error.
Related
The title probably isn't very clear, what I'm talking about is:
Say you have a class A depending on B and a class B depending on A.
This causes a circular dependency, but can be solved pretty easily:
/// a.h
#ifndef __A_H
#define __A_H
struct B;
#include "b.h"
struct A
{
B *bptr;
A();
void doStuffWithB();
};
#endif
/// b.h
#ifndef __B_H
#define __B_H
struct A;
#include "a.h"
struct B
{
A *aptr;
B();
void doStuffWithA();
};
#endif
Boom! Circular dependency resolved.
However, what if I now wanted to use an enum declared in B as an argument in A ?
/// a.h ...
struct A
{
B *bptr;
A();
void doStuffWithB(B::Type type); // <-- Compiler smells something funny here
};
/// b.h ...
struct B
{
enum Type
{
// Whatever...
}
B();
void doStuffWithA();
};
Obviously it will not work because the enum isn't yet declared.
The solution for this would be to just put the enum in it's own header file, but it's really nice to have it attached to the class, so would there be any funny way to do something like that ? I searched around but couldn't find a satisfactory answer.
struct B;
#include "b.h"
In the original version of the two header files this #include is completely unnecessary. You'll be happy to learn that the struct B; forward declaration is completely sufficient for declaring the B * class member. The analogous thing applies for the struct A; and the #include in the other header file: the #include is unnecessary.
And once you made this fortunate discovery, the solution in this specific case becomes obvious: simply put back the #include "b.h" back wher eit was.
Only a.h needs to #include the other file, and fully declare the B object in order to make use of its inner enum. The reason for the original compilation error is the unneeded include from b.h to a.h.
When compiling the b.h, its #include of a.h happens before the class and its inner enum gets declared. Then, the #include from a.h to b.h does nothing, because it gets blocked by the include guards. And then the A class gets compiled without the B class, and its inner enum, getting declared.
So, this specific case can be solved, because the dependency on an inner class member is from one of the classes only. What is, actually, an insolvable problem is when two classes have a mutually dependency on each other's inner class member. The only solution is a refactoring, pulling out the inner class type/enums into the global scope, and perhaps using a using or a typedef to alias an inner class to it.
I have seen this type of error everywhere and, although I have looked at the answers, none seem to help.
I get the following error with the following piece of code:
error: 'A' has not been declared
B.h:
#include "A.h"
class B{
public:
static bool doX(A *a);
};
A.h:
include "B.h"
class A{};
To run off a checklist of things I've already tried:
- Names are spelled correctly
- A is in A.h
- There are no namespaces
- No templates
- No macros
I have other classes with can find A just fine. The only thing I can think of is that 'static' is causing a problem.
Replace the include with a forward declaration:
//B.h
class A;
class B{
public:
static bool doX(A *a);
};
Include files only when you have to.
Also, use include guards. This will prevent other nasty issues like re-definitions & such.
If you have two headers including each other you end up with a circular dependency, and due to the way the preprocessor works it means one will be defined before the other.
To fix, I would avoid including A.h in B.h, and just forward declare instead:
class A;
class B{
public:
static bool doX(A *a);
};
You can then include A.h in B.cpp
I have the following implementation:
header of A:
class A
{
public:
foo();
};
A has its own .cpp file with the implementation for foo()
//header of B
#include "A.h"
class B
{
public foo();
};
Note: B does not have a header of its own
Now in the Class C.cpp, I want to reuse header of A and implementation from B.o. So in C.cpp I do:
//C.cpp
#include "A.h"
....
B b;
b.foo();
..
When I compile the above I am bound to get redeclaration error for the function foo(). I want to know if there is any way to tell GNU compiler to take B.o and omit A.o... Or to tell compiler to consider the first object in the make file that contains the implementation and ignore the rest?
I am using GNU v2.16
Your problem is about redeclaration of A since in C.cpp it will see 2 declarations of A one through A.h and other through B.h, so just guard A.h in a header guard to avoid including it more than once, generally you should always guard your headers:
#ifndef HEADER_A_h_INCLUDED
#define HEADER_A_h_INCLUDED
class A {...};
#endif
Now if you include A.h more than one time this guard will make the second include as nothing!
Hi i have two classes A and B .
in A i am using the header file for B so that i can create an instance for B( e.g. B *b ) and the something i am doing in Class B also i.e including the header file of A and creating the instance for A(e.g. A *a) in B .
while i am including the header file for A in B it gives me the following error in A.h
1>c:\Bibek\A.h(150) : error C2143: syntax error : missing ';' before '*'
1>c:\Bibek\A.h(150)(150) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\Bibek\A.h(150)(150) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
It sounds like you are including the header files in a circular manner (A.h includes B.h, which includes A.h). Using header guards means that when B.h includes A.h in the above scenario, it skips that (due to the now active include guard of A.h), so the types in A.h are not yet defined when parsing B.h.
To fix, you can use forward declarations:
// A.h
#ifndef A_H
#define A_H
// no #include "B.h"
class B; // forward declaration of B
class A {
B* b;
};
#endif
similarly for B.h
This allows you to use pointers of the forward declared class (e.g. in declarations of member variables, member function declarations), but not use it in any other way in the header.
Then in A.cpp you need to have the proper definition of B.h, so you include it:
// A.cpp
#include "A.h"
#include "B.h" // get the proper definition of B
// external definitions of A's member functions
This construction avoids the circular inclusion of the header files while allowing full use of the types (in the .cpp files).
Note: the error about the non-support of default int happens as the compiler does not have the proper definition of A when including B.h, (the C language allows default int definition for unknown types, but this is not allowed in C++)
Suppose I have two .h files: A.h and B.h.
Moreover, A.h includes B.h itself:
B.h - defines class B.
class B {
...
};
A.h - defines class A, which uses class B.
#include B.h
class A {
void SomeFunction(const B& b);
};
Now, I have some .cpp file, that uses both A and B classes (B class maybe used not only in A::SomeFunction(B))
What are the pluses to include both A.h and B.h (instead of only A.h) from the perspective of design-patterns and coding style.
Including both "A.h" and "B.h" makes the dependencies completely clear. There is no reason why "A.h" could not have forward-declared class B, and so including both headers prevents your ".cpp" file from breaking should the transitive include be changed to a forward declaration. In general, it is not a good idea to rely on transitive includes, and instead one should explicitly include all direct dependencies. (Note that this does not apply for "master include" headers that are intended to give transitive includes).
This has nothing to do with design patterns. You would include B.h whenever you need to use the class B, and you would include A.h whenever you need to use the class A. If the class B is a design detail of class A, or otherwise closely associated with it, put it in A.h rather than in a separate header file.
I'd like to point out that when you do have header files, you should have a define to make sure it isn't included twice.
For example:
A.h:
#ifndef _A_H_
#define _A_H_
class A
{
};
#endif
B.h:
#ifndef _B_H_
#define _B_H_
#include "a.h"
class B : public A
{
};
#endif
I think the above makes the most sense because now you can include A and B as many times as you think you'll need, but it won't be compiled multiple times.