Reputation: 448
I have a question about when to use forward declaration vs. include header. I know that there are a lot of questions similar to this out there, but there's just one thing that's a bit confusing.
I've seen the following way in a source code I was looking at:
classA.h
#ifndef H_CLASSA
#define H_CLASSA
class classB;
class classA {
public:
classA(B* b);
};
and then in classA.cpp:
#include "classA.h"
#include "classB.h" // dependency
classA::classA(B* b) { b->someMethod(); }
In cases like this I've just put #include "class.b" in the classA-header from the start since A has a dependency on class B and uses it. But I don't get why you would forward declare classB first in the header and then include the classB.h in the source file?
Thanks in advance!
Upvotes: 3
Views: 2701
Reputation: 26476
In order to prevent circular including:
let's say we have the following include path: (each [] is a header file , each -> is include)
[A] -> [B] -> [C]
so far so good. BUT what happens if [A] has some classes or function which takes some objects from [C] as argument? So we can just include (like you said) [C] in [A]. no we can have the following problems : 1) this circular including can cause some errors compiler : first of all , C includes B , B includes A , but A include C! and the cycle continues recursively. 2) lets say [A] has a class A , [B] has a class B that inherits from A and [C] has a class C that inherits from B. let's say the compiler can handle error 1 , still, you'll probably get "Base class not defined" error, since [A] is compiled , before A is compiled all the headers that included ([B] and [C]) are compiled. C is compiled as sub class of A and B , but hey , B and A are not even exist at this point!
this is where forward declarations come handy. it allows me to say "there are 2 classes , B and C , there's still not compiled", and in the cpp file actually uses the header files
but this solution still has some problems . you can only use classes that are forward declared as pointers and references. but , even so, it's extremely recommended to pass objects as reference or const reference . so you can use C and B in [A] , as reference.
Upvotes: 1