0

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.

corazza
  • 31,222
  • 37
  • 115
  • 186

3 Answers3

4

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.

S.C. Madsen
  • 5,100
  • 5
  • 32
  • 50
1

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.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • Yes, pointers themselves do all have the same size, but when you increment a pointer, its address actually switches in memory by the size of the type it's pointing to. So I was wondering if that functionality would be impaired by forward declaring... – corazza Sep 21 '12 at 10:57
  • the compiler would tell you if it has a problem with only a forward declaration ;) – codeling Sep 21 '12 at 10:58
  • 1
    @Bane if you separate the implementation, it's fine. Are you moving the pointer in the header? If not, it's ok. – Luchian Grigore Sep 21 '12 at 10:59
  • @LuchianGrigore, I'm not moving the pointer in the header... So OK then. – corazza Sep 21 '12 at 11:04
  • As I recall, there is some rare case, where forward declaration cause trouble with virtual destructor. Something related to smart pointers. – KAction Sep 21 '12 at 11:04
  • @RandolphCarter, well, maybe it would just be silent. I don't see how it would generate an error... – corazza Sep 21 '12 at 11:04
  • @Bane: AFAIK, there is no situation where the compiler needs to know the size but won't complain about it... – codeling Sep 21 '12 at 11:06
  • @RandolphCarter, but my point was that the compiler **knows** the size, but the wrong one... But I'm a real newbie to C++, so I'm probably wrong. – corazza Sep 21 '12 at 11:07
  • 1
    If the type is forward declared, the type is *incomplete* until the actual definition is seen. Therefore the compiler knows that it doesn't know the size. In the case of a vector, which is a template class, its member functions are not instantiated until you call them (which in your case occurs in the implementation where the type is fully specified). – Pete Sep 21 '12 at 11:15
  • And also a vector of B*'s will be iterated with something equivalent to a B**. Incrementing a B** only needs to know the sizeof(B*). – Pete Sep 21 '12 at 11:17
1

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.

Community
  • 1
  • 1
PaperBirdMaster
  • 12,806
  • 9
  • 48
  • 94