Accessing classes defined in other files [duplicate] - c++

This question already has answers here:
Circular C++ Header Includes
(6 answers)
Closed 9 years ago.
My question is about linking the files in g++ compiler.
I have a .cpp file named A.cpp containing a parent class and its children, each class uses an instance of another class defined in B.cpp, and in the class defined in B.cpp, we use an instance of all the classes defined in A!
How should I link these files? Is this a very poor programming style?
I have tried including A.cpp in one B.cpp and B.cpp in A.cpp but it is incorrect.

You don't have to include A.cpp in B.cpp, you need to use an header file.
https://en.wikipedia.org/wiki/Header_file
Basically, an header file contains the definitions of your classes and methods.
If I've understand your example you need an A.h file that you will include in B.cpp

You should define a class in a header file. only the function and static data member definitions should be in a .cpp file.
You should also use compiler macros (#if defined / #define / #endif) to prevent multiple includes.
About A in B and B in A:
What you have stated would cause infinite recursion:
Each A contains a B, each of which contains and A, each of which contains a B, each of which contains an A ... and so on.
You cannot do that obviously. You can nevertheless, have for example an A-pointer int B and an instance of B in A.
I don't know what you want to achieve but you could use a constructor of B to pass in a pointer to the A object it is contained in (if this is always the case for example).
B.h
#if !defined(B_CLASS_H)
#define B_CLASS_H
class A; // forward declare A, no include "A.h" here
class B
{
A * a_pointer;
public:
B (A* another_A);
};
#endif
B.cc
#include "B.h"
B::B (A* another_A) : a_pointer(another_A) { }
A.h
#if !defined(A_CLASS_H)
#define A_CLASS_H
#include "B.h"
class A
{
B b_instance;
public:
A (void);
};
#endif
A.cc
#include "A.h"
A::A (void) : b_instance(this) { }

Related

C++: Has Not Been Declared

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

Resolve linker errors in GNU for redeclaration

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!

May I #include in .hpp files?

I have a class called A, which has its .cpp and .hpp files. It depends on classes B and C. Now, I'm wondering, should I #include B.hpp and #include C.hpp in A.cpp or A.hpp? I think it would be beneficial for me to #include in the A.hpp file, because I'm creating a vector of B*'s, and I'm not sure that the compiler will know the correct size of B if I only forward declare it (so I couldn't pointer increment correctly)... By "forward declaration", I mean writing class B; and class C; in the beggining of A.hpp.
As already mentioned, you can often work-around having to #include stuff by using forward declarations, and indeed the best practice is to minimize the amount of other headers included.
But: To answer your questions headline: yes you may, and the common mechanism to avoid "circular inclusion" is the following
A.hpp:
#ifndef A_HPP_INCLUDED
#define A_HPP_INCLUDED
... // code
#endif
Now if say B.hpp includes A.hpp, and subsequently, C.hpp looks like:
#ifndef C_HPP_INCLUDED
#define C_HPP_INCLUDED
#include "A.hpp"
#include "B.hpp"
...
#endif
Then you won't get an error stating that e.g. 'class A' has already been defined.
If it's a vector of B*, you don't need to include B.hpp in the other header. A forward declaration is fine. Pointers have the same size, regardless of what they point to.
It's preferred to have includes only when necessary, and this certainly looks like it's not.
I don't know if i understand your class hierarchy, in my mind is like this:
B.hpp
class B
{
B();
};
B.cpp
B::B() {};
C.hpp
class C
{
C();
};
A.cpp
A::A() {};
A.hpp
class A
{
A();
B *b;
C *C;
};
A.cpp
#include "B.hpp"
#include "C.hpp"
A::A() :
b(NULL), c(NULL)
{
};
Is this correct? (if not, please think about provide some code ;) If your class A have pointers to class B and class C a forward declaration must be the only thing you need.
I'm not sure that the compiler will know the correct size of B if I only forward declare it
Yes, as long as you include the B.hpp and C.hpp in the A.cpp file the compiler would be able to deduce its size (the class size, the pointer size is always the same). Why? Just because in the cpp file it knows the correct size due the #include. I've found this answer that would be useful to understand what I', trying to say.
Would be fine in the hpp file instead? Maybe, if your A.hpp would not be included in other files the class B and class C does not bother and spreading into another files. So, if it is the case that would not be neccessary. But IMHO the best practice is to forward declare and #include in the cpp files when it is possible.

including .h files

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.

can two classes see each other using C++?

So I have a class A, where I want to call some class B functions. So I include "b.h". But, in class B, I want to call a class A function. If I include "a.h", it ends up in an infinite loop, right? What can I do about it?
Put only member function declarations in header (.h) files, and put member function definitions in implementation (.cpp) files. Then your header files do not need to include each other, and you can include both headers in either implementation file.
For cases when you need to reference the other class in member signatures as well, you can use a forward declaration:
class A;
This lets you use pointer and reference types (A* and A&), though not A itself. It also doesn't let you call members.
Example:
// a.h
struct B; // forward declaration
struct A {
void foo(B* b); // pointers and references to forward-declared classes are ok
};
// b.h
struct A; // forward declaration
struct B {
void bar(A& a); // pointers and references to forward-declared classes are ok
};
// a.cpp
#include "a.h"
#include "b.h"
void A::foo(B* b) {
b->bar(*this); // full declaration of B visible, ok to call members now
}
// b.cpp
#include "a.h"
#include "b.h"
void B::bar(A& a) {
a.foo(this); // full declaration of A visible, ok to call members now
}
Each class (A and B) should have a header file and an implementation file.
Each header file (e.g. A.h) should not include the other header file (e.g. B.h) but may include a forward reference to the other class (e.g. a statement like class B;), and may then use pointers and/or references to the other class in its declaration (e.g. class A may contain a B* as a data member and/or as a method parameter).
Each CPP file (e.g. A.cpp) may include more than one header file (e.g. A.h and B.h). It's recommended that each CPP file should include its own header file first (e.g. A.cpp should include A.h and then B.h, whereas B.cpp should include B.h and then A.h).
Each header file should contain only the declaration, and not the definition of the class: for example it will list the signatures of the class' methods, but not the method bodies/implementations (the method bodies/implementations will be in the .cpp file, not in the header file). Because the header files don't contain implemention details, they therefore don't depend on (don't need to see) details of other classes; at most they need to know that, for example, B is the name of a class: which it can get from a forward declaratin, instead of by including a header file in another header file.
You can also use forward declarations to get around the issue.
Try putting #ifndef, #define and #endif around your .h files.