Resolve build errors due to circular dependency amongst classes












296















I often find myself in a situation where I am facing multiple compilation/linker errors in a C++ project due to some bad design decisions (made by someone else :) ) which lead to circular dependencies between C++ classes in different header files (can happen also in the same file). But fortunately(?) this doesn't happen often enough for me to remember the solution to this problem for the next time it happens again.



So for the purposes of easy recall in the future I am going to post a representative problem and a solution along with it. Better solutions are of-course welcome.







  • A.h



    class B;
    class A
    {
    int _val;
    B *_b;
    public:

    A(int val)
    :_val(val)
    {
    }

    void SetB(B *b)
    {
    _b = b;
    _b->Print(); // COMPILER ERROR: C2027: use of undefined type 'B'
    }

    void Print()
    {
    cout<<"Type:A val="<<_val<<endl;
    }
    };







  • B.h



    #include "A.h"
    class B
    {
    double _val;
    A* _a;
    public:

    B(double val)
    :_val(val)
    {
    }

    void SetA(A *a)
    {
    _a = a;
    _a->Print();
    }

    void Print()
    {
    cout<<"Type:B val="<<_val<<endl;
    }
    };







  • main.cpp



    #include "B.h"
    #include <iostream>

    int main(int argc, char* argv)
    {
    A a(10);
    B b(3.14);
    a.Print();
    a.SetB(&b);
    b.Print();
    b.SetA(&a);
    return 0;
    }











share|improve this question




















  • 17





    When working with Visual Studio, the /showIncludes flag helps a lot to debug this kind of problems.

    – wip
    Sep 12 '12 at 3:08






  • 3





    The above link appears to have moved. Here's the new link for /showIncludes on MSDN

    – Tas
    Oct 26 '17 at 4:30
















296















I often find myself in a situation where I am facing multiple compilation/linker errors in a C++ project due to some bad design decisions (made by someone else :) ) which lead to circular dependencies between C++ classes in different header files (can happen also in the same file). But fortunately(?) this doesn't happen often enough for me to remember the solution to this problem for the next time it happens again.



So for the purposes of easy recall in the future I am going to post a representative problem and a solution along with it. Better solutions are of-course welcome.







  • A.h



    class B;
    class A
    {
    int _val;
    B *_b;
    public:

    A(int val)
    :_val(val)
    {
    }

    void SetB(B *b)
    {
    _b = b;
    _b->Print(); // COMPILER ERROR: C2027: use of undefined type 'B'
    }

    void Print()
    {
    cout<<"Type:A val="<<_val<<endl;
    }
    };







  • B.h



    #include "A.h"
    class B
    {
    double _val;
    A* _a;
    public:

    B(double val)
    :_val(val)
    {
    }

    void SetA(A *a)
    {
    _a = a;
    _a->Print();
    }

    void Print()
    {
    cout<<"Type:B val="<<_val<<endl;
    }
    };







  • main.cpp



    #include "B.h"
    #include <iostream>

    int main(int argc, char* argv)
    {
    A a(10);
    B b(3.14);
    a.Print();
    a.SetB(&b);
    b.Print();
    b.SetA(&a);
    return 0;
    }











share|improve this question




















  • 17





    When working with Visual Studio, the /showIncludes flag helps a lot to debug this kind of problems.

    – wip
    Sep 12 '12 at 3:08






  • 3





    The above link appears to have moved. Here's the new link for /showIncludes on MSDN

    – Tas
    Oct 26 '17 at 4:30














296












296








296


170






I often find myself in a situation where I am facing multiple compilation/linker errors in a C++ project due to some bad design decisions (made by someone else :) ) which lead to circular dependencies between C++ classes in different header files (can happen also in the same file). But fortunately(?) this doesn't happen often enough for me to remember the solution to this problem for the next time it happens again.



So for the purposes of easy recall in the future I am going to post a representative problem and a solution along with it. Better solutions are of-course welcome.







  • A.h



    class B;
    class A
    {
    int _val;
    B *_b;
    public:

    A(int val)
    :_val(val)
    {
    }

    void SetB(B *b)
    {
    _b = b;
    _b->Print(); // COMPILER ERROR: C2027: use of undefined type 'B'
    }

    void Print()
    {
    cout<<"Type:A val="<<_val<<endl;
    }
    };







  • B.h



    #include "A.h"
    class B
    {
    double _val;
    A* _a;
    public:

    B(double val)
    :_val(val)
    {
    }

    void SetA(A *a)
    {
    _a = a;
    _a->Print();
    }

    void Print()
    {
    cout<<"Type:B val="<<_val<<endl;
    }
    };







  • main.cpp



    #include "B.h"
    #include <iostream>

    int main(int argc, char* argv)
    {
    A a(10);
    B b(3.14);
    a.Print();
    a.SetB(&b);
    b.Print();
    b.SetA(&a);
    return 0;
    }











share|improve this question
















I often find myself in a situation where I am facing multiple compilation/linker errors in a C++ project due to some bad design decisions (made by someone else :) ) which lead to circular dependencies between C++ classes in different header files (can happen also in the same file). But fortunately(?) this doesn't happen often enough for me to remember the solution to this problem for the next time it happens again.



So for the purposes of easy recall in the future I am going to post a representative problem and a solution along with it. Better solutions are of-course welcome.







  • A.h



    class B;
    class A
    {
    int _val;
    B *_b;
    public:

    A(int val)
    :_val(val)
    {
    }

    void SetB(B *b)
    {
    _b = b;
    _b->Print(); // COMPILER ERROR: C2027: use of undefined type 'B'
    }

    void Print()
    {
    cout<<"Type:A val="<<_val<<endl;
    }
    };







  • B.h



    #include "A.h"
    class B
    {
    double _val;
    A* _a;
    public:

    B(double val)
    :_val(val)
    {
    }

    void SetA(A *a)
    {
    _a = a;
    _a->Print();
    }

    void Print()
    {
    cout<<"Type:B val="<<_val<<endl;
    }
    };







  • main.cpp



    #include "B.h"
    #include <iostream>

    int main(int argc, char* argv)
    {
    A a(10);
    B b(3.14);
    a.Print();
    a.SetB(&b);
    b.Print();
    b.SetA(&a);
    return 0;
    }








c++ compiler-errors circular-dependency c++-faq






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Oct 12 '17 at 14:20









StoryTeller

98.1k12200268




98.1k12200268










asked Mar 9 '09 at 10:57









AutodidactAutodidact

16.8k145576




16.8k145576








  • 17





    When working with Visual Studio, the /showIncludes flag helps a lot to debug this kind of problems.

    – wip
    Sep 12 '12 at 3:08






  • 3





    The above link appears to have moved. Here's the new link for /showIncludes on MSDN

    – Tas
    Oct 26 '17 at 4:30














  • 17





    When working with Visual Studio, the /showIncludes flag helps a lot to debug this kind of problems.

    – wip
    Sep 12 '12 at 3:08






  • 3





    The above link appears to have moved. Here's the new link for /showIncludes on MSDN

    – Tas
    Oct 26 '17 at 4:30








17




17





When working with Visual Studio, the /showIncludes flag helps a lot to debug this kind of problems.

– wip
Sep 12 '12 at 3:08





When working with Visual Studio, the /showIncludes flag helps a lot to debug this kind of problems.

– wip
Sep 12 '12 at 3:08




3




3





The above link appears to have moved. Here's the new link for /showIncludes on MSDN

– Tas
Oct 26 '17 at 4:30





The above link appears to have moved. Here's the new link for /showIncludes on MSDN

– Tas
Oct 26 '17 at 4:30












9 Answers
9






active

oldest

votes


















237














The way to think about this is to "think like a compiler".



Imagine you are writing a compiler. And you see code like this.



// file: A.h
class A {
B _b;
};

// file: B.h
class B {
A _a;
};

// file main.cc
#include "A.h"
#include "B.h"
int main(...) {
A a;
}


When you are compiling the .cc file (remember that the .cc and not the .h is the unit of compilation), you need to allocate space for object A. So, well, how much space then? Enough to store B! What's the size of B then? Enough to store A! Oops.



Clearly a circular reference that you must break.



You can break it by allowing the compiler to instead reserve as much space as it knows about upfront - pointers and references, for example, will always be 32 or 64 bits (depending on the architecture) and so if you replaced (either one) by a pointer or reference, things would be great. Let's say we replace in A:



// file: A.h
class A {
// both these are fine, so are various const versions of the same.
B& _b_ref;
B* _b_ptr;
};


Now things are better. Somewhat. main() still says:



// file: main.cc
#include "A.h" // <-- Houston, we have a problem


#include, for all extents and purposes (if you take the preprocessor out) just copies the file into the .cc. So really, the .cc looks like:



// file: partially_pre_processed_main.cc
class A {
B& _b_ref;
B* _b_ptr;
};
#include "B.h"
int main (...) {
A a;
}


You can see why the compiler can't deal with this - it has no idea what B is - it has never even seen the symbol before.



So let's tell the compiler about B. This is known as a forward declaration, and is discussed further in this answer.



// main.cc
class B;
#include "A.h"
#include "B.h"
int main (...) {
A a;
}


This works. It is not great. But at this point you should have an understanding of the circular reference problem and what we did to "fix" it, albeit the fix is bad.



The reason this fix is bad is because the next person to #include "A.h" will have to declare B before they can use it and will get a terrible #include error. So let's move the declaration into A.h itself.



// file: A.h
class B;
class A {
B* _b; // or any of the other variants.
};


And in B.h, at this point, you can just #include "A.h" directly.



// file: B.h
#include "A.h"
class B {
// note that this is cool because the compiler knows by this time
// how much space A will need.
A _a;
}


HTH.






share|improve this answer





















  • 16





    "Telling the compiler about B" is known as a forward declaration of B.

    – Peter Ajtai
    Nov 17 '10 at 1:57






  • 7





    Omg! totally missed the fact that references are known in terms of occupied space. Finally, now I can design properly!

    – kellogs
    Nov 7 '11 at 2:31






  • 33





    But still You cannot use any function on B (as in the question _b->Printt())

    – rank1
    Apr 17 '13 at 11:02






  • 3





    This is the issue I'm having. How do you bring the functions in with forward declaration without completely rewriting the header file?

    – sydan
    Feb 3 '15 at 13:56






  • 2





    @sydan: You can't. Resolving circular dependencies requires out-of-class definitions.

    – Ben Voigt
    Apr 11 '15 at 14:03



















93














You can avoid compilation errors if you remove the method definitions from the header files and let the classes contain only the method declarations and variable declarations/definitions. The method definitions should be placed in a .cpp file (just like a best practice guideline says).



The down side of the following solution is (assuming that you had placed the methods in the header file to inline them) that the methods are no longer inlined by the compiler and trying to use the inline keyword produces linker errors.



//A.h
#ifndef A_H
#define A_H
class B;
class A
{
int _val;
B* _b;
public:

A(int val);
void SetB(B *b);
void Print();
};
#endif

//B.h
#ifndef B_H
#define B_H
class A;
class B
{
double _val;
A* _a;
public:

B(double val);
void SetA(A *a);
void Print();
};
#endif

//A.cpp
#include "A.h"
#include "B.h"

#include <iostream>

using namespace std;

A::A(int val)
:_val(val)
{
}

void A::SetB(B *b)
{
_b = b;
cout<<"Inside SetB()"<<endl;
_b->Print();
}

void A::Print()
{
cout<<"Type:A val="<<_val<<endl;
}

//B.cpp
#include "B.h"
#include "A.h"
#include <iostream>

using namespace std;

B::B(double val)
:_val(val)
{
}

void B::SetA(A *a)
{
_a = a;
cout<<"Inside SetA()"<<endl;
_a->Print();
}

void B::Print()
{
cout<<"Type:B val="<<_val<<endl;
}

//main.cpp
#include "A.h"
#include "B.h"

int main(int argc, char* argv)
{
A a(10);
B b(3.14);
a.Print();
a.SetB(&b);
b.Print();
b.SetA(&a);
return 0;
}





share|improve this answer


























  • Thanks. This solved the problem easily. I simply moved the circular includes to the .cpp files.

    – Lenar Hoyt
    Oct 4 '14 at 18:16











  • yes, this is how you can solve circular dependecies

    – Guru
    Oct 16 '14 at 4:41






  • 3





    What if you have a template method? Then you can't really move it into a CPP file unless you instantiate the templates manually.

    – Malcolm
    Sep 1 '16 at 12:55











  • You always include "A.h" and "B.h" together. Why don't you include "A.h" in "B.h" and then include only "B.h" in both "A.cpp" and "B.cpp"?

    – Gusev Slava
    Sep 30 '18 at 4:25



















17














Things to remember:




  • This won't work if class A has an object of class B as a member or vice versa.

  • Forward declaration is way to go.

  • Order of declaration matters (which is why you are moving out the definitions).


    • If both classes call functions of the other, you have to move the definitions out.




Read the FAQ:




  • How can I create two classes that both know about each other?

  • What special considerations are needed when forward declarations are used with member objects?

  • What special considerations are needed when forward declarations are used with inline functions?






share|improve this answer





















  • 1





    the links you provided dont work anymore, do you happen to know the new ones to refer to?

    – Ramya Rao
    Feb 22 '17 at 22:11



















13














I'm late answering this, but there's not one reasonable answer to date, despite being a popular question with highly upvoted answers....



Best practice: forward declaration headers



As illustrated by the Standard library's <iosfwd> header, the proper way to provide forward declarations for others is to have a forward declaration header. For example:



a.fwd.h:



#pragma once
class A;


a.h:



#pragma once
#include "a.fwd.h"
#include "b.fwd.h"

class A
{
public:
void f(B*);
};


b.fwd.h:



#pragma once
class B;


b.h:



#pragma once
#include "b.fwd.h"
#include "a.fwd.h"

class B
{
public:
void f(A*);
};


The maintainers of the A and B libraries should each be responsible for keeping their forward declaration headers in sync with their headers and implementation files, so - for example - if the maintainer of "B" comes along and rewrites the code to be...



b.fwd.h:



template <typename T> class Basic_B;
typedef Basic_B<char> B;


b.h:



template <typename T>
class Basic_B
{
...class definition...
};
typedef Basic_B<char> B;


...then recompilation of the code for "A" will be triggered by the changes to the included b.fwd.h and should complete cleanly.





Poor but common practice: forward declare stuff in other libs



Say - instead of using a forward declaration header as explained above - code in a.h or a.cc instead forward-declares class B; itself:




  • if a.h or a.cc did include b.h later:


    • compilation of A will terminate with an error once it gets to the conflicting declaration/definition of B (i.e. the above change to B broke A and any other clients abusing forward declarations, instead of working transparently).



  • otherwise (if A didn't eventually include b.h - possible if A just stores/passes around Bs by pointer and/or reference)


    • build tools relying on #include analysis and changed file timestamps won't rebuild A (and its further-dependent code) after the change to B, causing errors at link time or run time. If B is distributed as a runtime loaded DLL, code in "A" may fail to find the differently-mangled symbols at runtime, which may or may not be handled well enough to trigger orderly shutdown or acceptably reduced functionality.




If A's code has template specialisations / "traits" for the old B, they won't take effect.






share|improve this answer





















  • 1





    This is a really clean way to handle the forward declarations. The only "disadvantage" would be in the extra files. I assume you always include a.fwd.h in a.h, to assure they stay in sync. The example code is missing where these classes are used. a.h and b.h will both need to be included since they won't function in isolation: ``` //main.cpp #include "a.h" #include "b.h" int main() { ... } ``` Or one of them needs to be fully included in the other like in the opening question. Where b.h includes a.h and main.cpp includes b.h

    – Farway
    May 5 '17 at 16:37








  • 2





    @Farway Right on all counts. I didn't bother showing main.cpp, but nice that you've documented what it should contain in your comment. Cheers

    – Tony Delroy
    May 5 '17 at 20:42






  • 1





    One of the better answers with a nice detailed explanation of why with the does and don'ts due to the pros and cons...

    – Francis Cugler
    Jan 16 '18 at 5:06






  • 1





    @RezaHajianpour: it makes sense to have a forward declaration header for all classes that you want forward declarations of, circular or not. That said, you will only want them when: 1) including the actual declaration is (or can be anticipated to later become) costly (e.g. it includes a lot of headers your translation unit might not otherwise need), and 2) client code is likely to be able to make use of pointers or references to the objects. <iosfwd> is a classic example: there can be a few stream objects referenced from many places, and <iostream> is a lot to include.

    – Tony Delroy
    Jan 23 at 5:02






  • 1





    @RezaHajianpour: I think you have the right idea, but there's a terminological issue with your statement: "we just need the type to be declared" would be right. The type being declared means the forward declaration has been seen; it's defined once the full definition has been parsed (and for that you may need more #includes).

    – Tony Delroy
    Jan 25 at 14:45





















11














I once solved this kind of problem by moving all inlines after the class definition and putting the #include for the other classes just before the inlines in the header file. This way one make sure all definitions+inlines are set prior the inlines are parsed.



Doing like this makes it possible to still have a bunch of inlines in both(or multiple) header files. But it's necessary to have include guards.



Like this



// File: A.h
#ifndef __A_H__
#define __A_H__
class B;
class A
{
int _val;
B *_b;
public:
A(int val);
void SetB(B *b);
void Print();
};

// Including class B for inline usage here
#include "B.h"

inline A::A(int val) : _val(val)
{
}

inline void A::SetB(B *b)
{
_b = b;
_b->Print();
}

inline void A::Print()
{
cout<<"Type:A val="<<_val<<endl;
}

#endif /* __A_H__ */


...and doing the same in B.h






share|improve this answer


























  • Why? I think it's an elegant solution to a tricky problem...when one wants inlines. If one don't want inlines one shouldn't have written the code like it was written from start...

    – epatel
    Mar 10 '09 at 20:01











  • What happens if a user includes B.h first?

    – Mr Fooz
    Mar 18 '14 at 16:00






  • 3





    Note that your header guard is using a reserved identifier, anything with double adjacent underscores is reserved.

    – Lars Viklund
    Aug 10 '15 at 15:09



















6














I've written a post about this once: Resolving circular dependencies in c++



The basic technique is to decouple the classes using interfaces. So in your case:



//Printer.h
class Printer {
public:
virtual Print() = 0;
}

//A.h
#include "Printer.h"
class A: public Printer
{
int _val;
Printer *_b;
public:

A(int val)
:_val(val)
{
}

void SetB(Printer *b)
{
_b = b;
_b->Print();
}

void Print()
{
cout<<"Type:A val="<<_val<<endl;
}
};

//B.h
#include "Printer.h"
class B: public Printer
{
double _val;
Printer* _a;
public:

B(double val)
:_val(val)
{
}

void SetA(Printer *a)
{
_a = a;
_a->Print();
}

void Print()
{
cout<<"Type:B val="<<_val<<endl;
}
};

//main.cpp
#include <iostream>
#include "A.h"
#include "B.h"

int main(int argc, char* argv)
{
A a(10);
B b(3.14);
a.Print();
a.SetB(&b);
b.Print();
b.SetA(&a);
return 0;
}





share|improve this answer





















  • 2





    Please note that use of interfaces and virtual has runtime performance impacts.

    – cemper93
    Jun 22 '16 at 19:10



















3














Here is the solution for templates: How to handle circular dependencies with templates



The clue to solving this problem is to declare both classes before providing the definitions (implementations). It’s not possible to split the declaration and definition into separate files, but you can structure them as if they were in separate files.






share|improve this answer

































    2














    The simple example presented on Wikipedia worked for me.
    (you can read the complete description at http://en.wikipedia.org/wiki/Circular_dependency#Example_of_circular_dependencies_in_C.2B.2B )



    File '''a.h''':



    #ifndef A_H
    #define A_H

    class B; //forward declaration

    class A {
    public:
    B* b;
    };
    #endif //A_H


    File '''b.h''':



    #ifndef B_H
    #define B_H

    class A; //forward declaration

    class B {
    public:
    A* a;
    };
    #endif //B_H


    File '''main.cpp''':



    #include "a.h"
    #include "b.h"

    int main() {
    A a;
    B b;
    a.b = &b;
    b.a = &a;
    }





    share|improve this answer

































      0














      Unfortunately, all the previous answers are missing some details. The correct solution is a little bit cumbersome, but this is the only way to do it properly. And it scales easily, handles more complex dependencies as well.



      Here's how you can do this, exactly retaining all the details, and usability:




      • the solution is exactly the same as originally intended

      • inline functions still inline

      • users of A and B can include A.h and B.h in any order


      Create two files, A_def.h, B_def.h. These will contain only A's and B's definition:



      // A_def.h
      #ifndef A_DEF_H
      #define A_DEF_H

      class B;
      class A
      {
      int _val;
      B *_b;

      public:
      A(int val);
      void SetB(B *b);
      void Print();
      };
      #endif

      // B_def.h
      #ifndef B_DEF_H
      #define B_DEF_H

      class A;
      class B
      {
      double _val;
      A* _a;

      public:
      B(double val);
      void SetA(A *a);
      void Print();
      };
      #endif


      And then, A.h and B.h will contain this:



      // A.h
      #ifndef A_H
      #define A_H

      #include "A_def.h"
      #include "B_def.h"

      inline A::A(int val) :_val(val)
      {
      }

      inline void A::SetB(B *b)
      {
      _b = b;
      _b->Print();
      }

      inline void A::Print()
      {
      cout<<"Type:A val="<<_val<<endl;
      }

      #endif

      // B.h
      #ifndef B_H
      #define B_H

      #include "A_def.h"
      #include "B_def.h"

      inline B::B(double val) :_val(val)
      {
      }

      inline void B::SetA(A *a)
      {
      _a = a;
      _a->Print();
      }

      inline void B::Print()
      {
      cout<<"Type:B val="<<_val<<endl;
      }

      #endif


      Note that A_def.h and B_def.h are "private" headers, users of A and B should not use them. The public header is A.h and B.h.






      share|improve this answer
























      • Does this have any advantages over Tony Delroy's solution? Both are based on "helper" headers, but Tony's are smaller (they just contain the forward declaration) and they seem to be working the same way (at least at first glance).

        – Fabio Turati
        Nov 20 '18 at 11:33











      • That answer doesn't solve the original problem. It just says "put forward declarations into a separate header". Nothing about resolving circular dependency (the question needs a solution where A's and B's definition is available, forward declaration is not enough).

        – geza
        Nov 20 '18 at 11:50










      protected by StoryTeller Oct 12 '17 at 14:13



      Thank you for your interest in this question.
      Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



      Would you like to answer one of these unanswered questions instead?














      9 Answers
      9






      active

      oldest

      votes








      9 Answers
      9






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      237














      The way to think about this is to "think like a compiler".



      Imagine you are writing a compiler. And you see code like this.



      // file: A.h
      class A {
      B _b;
      };

      // file: B.h
      class B {
      A _a;
      };

      // file main.cc
      #include "A.h"
      #include "B.h"
      int main(...) {
      A a;
      }


      When you are compiling the .cc file (remember that the .cc and not the .h is the unit of compilation), you need to allocate space for object A. So, well, how much space then? Enough to store B! What's the size of B then? Enough to store A! Oops.



      Clearly a circular reference that you must break.



      You can break it by allowing the compiler to instead reserve as much space as it knows about upfront - pointers and references, for example, will always be 32 or 64 bits (depending on the architecture) and so if you replaced (either one) by a pointer or reference, things would be great. Let's say we replace in A:



      // file: A.h
      class A {
      // both these are fine, so are various const versions of the same.
      B& _b_ref;
      B* _b_ptr;
      };


      Now things are better. Somewhat. main() still says:



      // file: main.cc
      #include "A.h" // <-- Houston, we have a problem


      #include, for all extents and purposes (if you take the preprocessor out) just copies the file into the .cc. So really, the .cc looks like:



      // file: partially_pre_processed_main.cc
      class A {
      B& _b_ref;
      B* _b_ptr;
      };
      #include "B.h"
      int main (...) {
      A a;
      }


      You can see why the compiler can't deal with this - it has no idea what B is - it has never even seen the symbol before.



      So let's tell the compiler about B. This is known as a forward declaration, and is discussed further in this answer.



      // main.cc
      class B;
      #include "A.h"
      #include "B.h"
      int main (...) {
      A a;
      }


      This works. It is not great. But at this point you should have an understanding of the circular reference problem and what we did to "fix" it, albeit the fix is bad.



      The reason this fix is bad is because the next person to #include "A.h" will have to declare B before they can use it and will get a terrible #include error. So let's move the declaration into A.h itself.



      // file: A.h
      class B;
      class A {
      B* _b; // or any of the other variants.
      };


      And in B.h, at this point, you can just #include "A.h" directly.



      // file: B.h
      #include "A.h"
      class B {
      // note that this is cool because the compiler knows by this time
      // how much space A will need.
      A _a;
      }


      HTH.






      share|improve this answer





















      • 16





        "Telling the compiler about B" is known as a forward declaration of B.

        – Peter Ajtai
        Nov 17 '10 at 1:57






      • 7





        Omg! totally missed the fact that references are known in terms of occupied space. Finally, now I can design properly!

        – kellogs
        Nov 7 '11 at 2:31






      • 33





        But still You cannot use any function on B (as in the question _b->Printt())

        – rank1
        Apr 17 '13 at 11:02






      • 3





        This is the issue I'm having. How do you bring the functions in with forward declaration without completely rewriting the header file?

        – sydan
        Feb 3 '15 at 13:56






      • 2





        @sydan: You can't. Resolving circular dependencies requires out-of-class definitions.

        – Ben Voigt
        Apr 11 '15 at 14:03
















      237














      The way to think about this is to "think like a compiler".



      Imagine you are writing a compiler. And you see code like this.



      // file: A.h
      class A {
      B _b;
      };

      // file: B.h
      class B {
      A _a;
      };

      // file main.cc
      #include "A.h"
      #include "B.h"
      int main(...) {
      A a;
      }


      When you are compiling the .cc file (remember that the .cc and not the .h is the unit of compilation), you need to allocate space for object A. So, well, how much space then? Enough to store B! What's the size of B then? Enough to store A! Oops.



      Clearly a circular reference that you must break.



      You can break it by allowing the compiler to instead reserve as much space as it knows about upfront - pointers and references, for example, will always be 32 or 64 bits (depending on the architecture) and so if you replaced (either one) by a pointer or reference, things would be great. Let's say we replace in A:



      // file: A.h
      class A {
      // both these are fine, so are various const versions of the same.
      B& _b_ref;
      B* _b_ptr;
      };


      Now things are better. Somewhat. main() still says:



      // file: main.cc
      #include "A.h" // <-- Houston, we have a problem


      #include, for all extents and purposes (if you take the preprocessor out) just copies the file into the .cc. So really, the .cc looks like:



      // file: partially_pre_processed_main.cc
      class A {
      B& _b_ref;
      B* _b_ptr;
      };
      #include "B.h"
      int main (...) {
      A a;
      }


      You can see why the compiler can't deal with this - it has no idea what B is - it has never even seen the symbol before.



      So let's tell the compiler about B. This is known as a forward declaration, and is discussed further in this answer.



      // main.cc
      class B;
      #include "A.h"
      #include "B.h"
      int main (...) {
      A a;
      }


      This works. It is not great. But at this point you should have an understanding of the circular reference problem and what we did to "fix" it, albeit the fix is bad.



      The reason this fix is bad is because the next person to #include "A.h" will have to declare B before they can use it and will get a terrible #include error. So let's move the declaration into A.h itself.



      // file: A.h
      class B;
      class A {
      B* _b; // or any of the other variants.
      };


      And in B.h, at this point, you can just #include "A.h" directly.



      // file: B.h
      #include "A.h"
      class B {
      // note that this is cool because the compiler knows by this time
      // how much space A will need.
      A _a;
      }


      HTH.






      share|improve this answer





















      • 16





        "Telling the compiler about B" is known as a forward declaration of B.

        – Peter Ajtai
        Nov 17 '10 at 1:57






      • 7





        Omg! totally missed the fact that references are known in terms of occupied space. Finally, now I can design properly!

        – kellogs
        Nov 7 '11 at 2:31






      • 33





        But still You cannot use any function on B (as in the question _b->Printt())

        – rank1
        Apr 17 '13 at 11:02






      • 3





        This is the issue I'm having. How do you bring the functions in with forward declaration without completely rewriting the header file?

        – sydan
        Feb 3 '15 at 13:56






      • 2





        @sydan: You can't. Resolving circular dependencies requires out-of-class definitions.

        – Ben Voigt
        Apr 11 '15 at 14:03














      237












      237








      237







      The way to think about this is to "think like a compiler".



      Imagine you are writing a compiler. And you see code like this.



      // file: A.h
      class A {
      B _b;
      };

      // file: B.h
      class B {
      A _a;
      };

      // file main.cc
      #include "A.h"
      #include "B.h"
      int main(...) {
      A a;
      }


      When you are compiling the .cc file (remember that the .cc and not the .h is the unit of compilation), you need to allocate space for object A. So, well, how much space then? Enough to store B! What's the size of B then? Enough to store A! Oops.



      Clearly a circular reference that you must break.



      You can break it by allowing the compiler to instead reserve as much space as it knows about upfront - pointers and references, for example, will always be 32 or 64 bits (depending on the architecture) and so if you replaced (either one) by a pointer or reference, things would be great. Let's say we replace in A:



      // file: A.h
      class A {
      // both these are fine, so are various const versions of the same.
      B& _b_ref;
      B* _b_ptr;
      };


      Now things are better. Somewhat. main() still says:



      // file: main.cc
      #include "A.h" // <-- Houston, we have a problem


      #include, for all extents and purposes (if you take the preprocessor out) just copies the file into the .cc. So really, the .cc looks like:



      // file: partially_pre_processed_main.cc
      class A {
      B& _b_ref;
      B* _b_ptr;
      };
      #include "B.h"
      int main (...) {
      A a;
      }


      You can see why the compiler can't deal with this - it has no idea what B is - it has never even seen the symbol before.



      So let's tell the compiler about B. This is known as a forward declaration, and is discussed further in this answer.



      // main.cc
      class B;
      #include "A.h"
      #include "B.h"
      int main (...) {
      A a;
      }


      This works. It is not great. But at this point you should have an understanding of the circular reference problem and what we did to "fix" it, albeit the fix is bad.



      The reason this fix is bad is because the next person to #include "A.h" will have to declare B before they can use it and will get a terrible #include error. So let's move the declaration into A.h itself.



      // file: A.h
      class B;
      class A {
      B* _b; // or any of the other variants.
      };


      And in B.h, at this point, you can just #include "A.h" directly.



      // file: B.h
      #include "A.h"
      class B {
      // note that this is cool because the compiler knows by this time
      // how much space A will need.
      A _a;
      }


      HTH.






      share|improve this answer















      The way to think about this is to "think like a compiler".



      Imagine you are writing a compiler. And you see code like this.



      // file: A.h
      class A {
      B _b;
      };

      // file: B.h
      class B {
      A _a;
      };

      // file main.cc
      #include "A.h"
      #include "B.h"
      int main(...) {
      A a;
      }


      When you are compiling the .cc file (remember that the .cc and not the .h is the unit of compilation), you need to allocate space for object A. So, well, how much space then? Enough to store B! What's the size of B then? Enough to store A! Oops.



      Clearly a circular reference that you must break.



      You can break it by allowing the compiler to instead reserve as much space as it knows about upfront - pointers and references, for example, will always be 32 or 64 bits (depending on the architecture) and so if you replaced (either one) by a pointer or reference, things would be great. Let's say we replace in A:



      // file: A.h
      class A {
      // both these are fine, so are various const versions of the same.
      B& _b_ref;
      B* _b_ptr;
      };


      Now things are better. Somewhat. main() still says:



      // file: main.cc
      #include "A.h" // <-- Houston, we have a problem


      #include, for all extents and purposes (if you take the preprocessor out) just copies the file into the .cc. So really, the .cc looks like:



      // file: partially_pre_processed_main.cc
      class A {
      B& _b_ref;
      B* _b_ptr;
      };
      #include "B.h"
      int main (...) {
      A a;
      }


      You can see why the compiler can't deal with this - it has no idea what B is - it has never even seen the symbol before.



      So let's tell the compiler about B. This is known as a forward declaration, and is discussed further in this answer.



      // main.cc
      class B;
      #include "A.h"
      #include "B.h"
      int main (...) {
      A a;
      }


      This works. It is not great. But at this point you should have an understanding of the circular reference problem and what we did to "fix" it, albeit the fix is bad.



      The reason this fix is bad is because the next person to #include "A.h" will have to declare B before they can use it and will get a terrible #include error. So let's move the declaration into A.h itself.



      // file: A.h
      class B;
      class A {
      B* _b; // or any of the other variants.
      };


      And in B.h, at this point, you can just #include "A.h" directly.



      // file: B.h
      #include "A.h"
      class B {
      // note that this is cool because the compiler knows by this time
      // how much space A will need.
      A _a;
      }


      HTH.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited May 23 '17 at 12:02









      Community

      11




      11










      answered Mar 9 '09 at 21:15









      RooshRoosh

      2,4382112




      2,4382112








      • 16





        "Telling the compiler about B" is known as a forward declaration of B.

        – Peter Ajtai
        Nov 17 '10 at 1:57






      • 7





        Omg! totally missed the fact that references are known in terms of occupied space. Finally, now I can design properly!

        – kellogs
        Nov 7 '11 at 2:31






      • 33





        But still You cannot use any function on B (as in the question _b->Printt())

        – rank1
        Apr 17 '13 at 11:02






      • 3





        This is the issue I'm having. How do you bring the functions in with forward declaration without completely rewriting the header file?

        – sydan
        Feb 3 '15 at 13:56






      • 2





        @sydan: You can't. Resolving circular dependencies requires out-of-class definitions.

        – Ben Voigt
        Apr 11 '15 at 14:03














      • 16





        "Telling the compiler about B" is known as a forward declaration of B.

        – Peter Ajtai
        Nov 17 '10 at 1:57






      • 7





        Omg! totally missed the fact that references are known in terms of occupied space. Finally, now I can design properly!

        – kellogs
        Nov 7 '11 at 2:31






      • 33





        But still You cannot use any function on B (as in the question _b->Printt())

        – rank1
        Apr 17 '13 at 11:02






      • 3





        This is the issue I'm having. How do you bring the functions in with forward declaration without completely rewriting the header file?

        – sydan
        Feb 3 '15 at 13:56






      • 2





        @sydan: You can't. Resolving circular dependencies requires out-of-class definitions.

        – Ben Voigt
        Apr 11 '15 at 14:03








      16




      16





      "Telling the compiler about B" is known as a forward declaration of B.

      – Peter Ajtai
      Nov 17 '10 at 1:57





      "Telling the compiler about B" is known as a forward declaration of B.

      – Peter Ajtai
      Nov 17 '10 at 1:57




      7




      7





      Omg! totally missed the fact that references are known in terms of occupied space. Finally, now I can design properly!

      – kellogs
      Nov 7 '11 at 2:31





      Omg! totally missed the fact that references are known in terms of occupied space. Finally, now I can design properly!

      – kellogs
      Nov 7 '11 at 2:31




      33




      33





      But still You cannot use any function on B (as in the question _b->Printt())

      – rank1
      Apr 17 '13 at 11:02





      But still You cannot use any function on B (as in the question _b->Printt())

      – rank1
      Apr 17 '13 at 11:02




      3




      3





      This is the issue I'm having. How do you bring the functions in with forward declaration without completely rewriting the header file?

      – sydan
      Feb 3 '15 at 13:56





      This is the issue I'm having. How do you bring the functions in with forward declaration without completely rewriting the header file?

      – sydan
      Feb 3 '15 at 13:56




      2




      2





      @sydan: You can't. Resolving circular dependencies requires out-of-class definitions.

      – Ben Voigt
      Apr 11 '15 at 14:03





      @sydan: You can't. Resolving circular dependencies requires out-of-class definitions.

      – Ben Voigt
      Apr 11 '15 at 14:03













      93














      You can avoid compilation errors if you remove the method definitions from the header files and let the classes contain only the method declarations and variable declarations/definitions. The method definitions should be placed in a .cpp file (just like a best practice guideline says).



      The down side of the following solution is (assuming that you had placed the methods in the header file to inline them) that the methods are no longer inlined by the compiler and trying to use the inline keyword produces linker errors.



      //A.h
      #ifndef A_H
      #define A_H
      class B;
      class A
      {
      int _val;
      B* _b;
      public:

      A(int val);
      void SetB(B *b);
      void Print();
      };
      #endif

      //B.h
      #ifndef B_H
      #define B_H
      class A;
      class B
      {
      double _val;
      A* _a;
      public:

      B(double val);
      void SetA(A *a);
      void Print();
      };
      #endif

      //A.cpp
      #include "A.h"
      #include "B.h"

      #include <iostream>

      using namespace std;

      A::A(int val)
      :_val(val)
      {
      }

      void A::SetB(B *b)
      {
      _b = b;
      cout<<"Inside SetB()"<<endl;
      _b->Print();
      }

      void A::Print()
      {
      cout<<"Type:A val="<<_val<<endl;
      }

      //B.cpp
      #include "B.h"
      #include "A.h"
      #include <iostream>

      using namespace std;

      B::B(double val)
      :_val(val)
      {
      }

      void B::SetA(A *a)
      {
      _a = a;
      cout<<"Inside SetA()"<<endl;
      _a->Print();
      }

      void B::Print()
      {
      cout<<"Type:B val="<<_val<<endl;
      }

      //main.cpp
      #include "A.h"
      #include "B.h"

      int main(int argc, char* argv)
      {
      A a(10);
      B b(3.14);
      a.Print();
      a.SetB(&b);
      b.Print();
      b.SetA(&a);
      return 0;
      }





      share|improve this answer


























      • Thanks. This solved the problem easily. I simply moved the circular includes to the .cpp files.

        – Lenar Hoyt
        Oct 4 '14 at 18:16











      • yes, this is how you can solve circular dependecies

        – Guru
        Oct 16 '14 at 4:41






      • 3





        What if you have a template method? Then you can't really move it into a CPP file unless you instantiate the templates manually.

        – Malcolm
        Sep 1 '16 at 12:55











      • You always include "A.h" and "B.h" together. Why don't you include "A.h" in "B.h" and then include only "B.h" in both "A.cpp" and "B.cpp"?

        – Gusev Slava
        Sep 30 '18 at 4:25
















      93














      You can avoid compilation errors if you remove the method definitions from the header files and let the classes contain only the method declarations and variable declarations/definitions. The method definitions should be placed in a .cpp file (just like a best practice guideline says).



      The down side of the following solution is (assuming that you had placed the methods in the header file to inline them) that the methods are no longer inlined by the compiler and trying to use the inline keyword produces linker errors.



      //A.h
      #ifndef A_H
      #define A_H
      class B;
      class A
      {
      int _val;
      B* _b;
      public:

      A(int val);
      void SetB(B *b);
      void Print();
      };
      #endif

      //B.h
      #ifndef B_H
      #define B_H
      class A;
      class B
      {
      double _val;
      A* _a;
      public:

      B(double val);
      void SetA(A *a);
      void Print();
      };
      #endif

      //A.cpp
      #include "A.h"
      #include "B.h"

      #include <iostream>

      using namespace std;

      A::A(int val)
      :_val(val)
      {
      }

      void A::SetB(B *b)
      {
      _b = b;
      cout<<"Inside SetB()"<<endl;
      _b->Print();
      }

      void A::Print()
      {
      cout<<"Type:A val="<<_val<<endl;
      }

      //B.cpp
      #include "B.h"
      #include "A.h"
      #include <iostream>

      using namespace std;

      B::B(double val)
      :_val(val)
      {
      }

      void B::SetA(A *a)
      {
      _a = a;
      cout<<"Inside SetA()"<<endl;
      _a->Print();
      }

      void B::Print()
      {
      cout<<"Type:B val="<<_val<<endl;
      }

      //main.cpp
      #include "A.h"
      #include "B.h"

      int main(int argc, char* argv)
      {
      A a(10);
      B b(3.14);
      a.Print();
      a.SetB(&b);
      b.Print();
      b.SetA(&a);
      return 0;
      }





      share|improve this answer


























      • Thanks. This solved the problem easily. I simply moved the circular includes to the .cpp files.

        – Lenar Hoyt
        Oct 4 '14 at 18:16











      • yes, this is how you can solve circular dependecies

        – Guru
        Oct 16 '14 at 4:41






      • 3





        What if you have a template method? Then you can't really move it into a CPP file unless you instantiate the templates manually.

        – Malcolm
        Sep 1 '16 at 12:55











      • You always include "A.h" and "B.h" together. Why don't you include "A.h" in "B.h" and then include only "B.h" in both "A.cpp" and "B.cpp"?

        – Gusev Slava
        Sep 30 '18 at 4:25














      93












      93








      93







      You can avoid compilation errors if you remove the method definitions from the header files and let the classes contain only the method declarations and variable declarations/definitions. The method definitions should be placed in a .cpp file (just like a best practice guideline says).



      The down side of the following solution is (assuming that you had placed the methods in the header file to inline them) that the methods are no longer inlined by the compiler and trying to use the inline keyword produces linker errors.



      //A.h
      #ifndef A_H
      #define A_H
      class B;
      class A
      {
      int _val;
      B* _b;
      public:

      A(int val);
      void SetB(B *b);
      void Print();
      };
      #endif

      //B.h
      #ifndef B_H
      #define B_H
      class A;
      class B
      {
      double _val;
      A* _a;
      public:

      B(double val);
      void SetA(A *a);
      void Print();
      };
      #endif

      //A.cpp
      #include "A.h"
      #include "B.h"

      #include <iostream>

      using namespace std;

      A::A(int val)
      :_val(val)
      {
      }

      void A::SetB(B *b)
      {
      _b = b;
      cout<<"Inside SetB()"<<endl;
      _b->Print();
      }

      void A::Print()
      {
      cout<<"Type:A val="<<_val<<endl;
      }

      //B.cpp
      #include "B.h"
      #include "A.h"
      #include <iostream>

      using namespace std;

      B::B(double val)
      :_val(val)
      {
      }

      void B::SetA(A *a)
      {
      _a = a;
      cout<<"Inside SetA()"<<endl;
      _a->Print();
      }

      void B::Print()
      {
      cout<<"Type:B val="<<_val<<endl;
      }

      //main.cpp
      #include "A.h"
      #include "B.h"

      int main(int argc, char* argv)
      {
      A a(10);
      B b(3.14);
      a.Print();
      a.SetB(&b);
      b.Print();
      b.SetA(&a);
      return 0;
      }





      share|improve this answer















      You can avoid compilation errors if you remove the method definitions from the header files and let the classes contain only the method declarations and variable declarations/definitions. The method definitions should be placed in a .cpp file (just like a best practice guideline says).



      The down side of the following solution is (assuming that you had placed the methods in the header file to inline them) that the methods are no longer inlined by the compiler and trying to use the inline keyword produces linker errors.



      //A.h
      #ifndef A_H
      #define A_H
      class B;
      class A
      {
      int _val;
      B* _b;
      public:

      A(int val);
      void SetB(B *b);
      void Print();
      };
      #endif

      //B.h
      #ifndef B_H
      #define B_H
      class A;
      class B
      {
      double _val;
      A* _a;
      public:

      B(double val);
      void SetA(A *a);
      void Print();
      };
      #endif

      //A.cpp
      #include "A.h"
      #include "B.h"

      #include <iostream>

      using namespace std;

      A::A(int val)
      :_val(val)
      {
      }

      void A::SetB(B *b)
      {
      _b = b;
      cout<<"Inside SetB()"<<endl;
      _b->Print();
      }

      void A::Print()
      {
      cout<<"Type:A val="<<_val<<endl;
      }

      //B.cpp
      #include "B.h"
      #include "A.h"
      #include <iostream>

      using namespace std;

      B::B(double val)
      :_val(val)
      {
      }

      void B::SetA(A *a)
      {
      _a = a;
      cout<<"Inside SetA()"<<endl;
      _a->Print();
      }

      void B::Print()
      {
      cout<<"Type:B val="<<_val<<endl;
      }

      //main.cpp
      #include "A.h"
      #include "B.h"

      int main(int argc, char* argv)
      {
      A a(10);
      B b(3.14);
      a.Print();
      a.SetB(&b);
      b.Print();
      b.SetA(&a);
      return 0;
      }






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Jan 5 '15 at 12:31

























      answered Mar 9 '09 at 10:57









      AutodidactAutodidact

      16.8k145576




      16.8k145576













      • Thanks. This solved the problem easily. I simply moved the circular includes to the .cpp files.

        – Lenar Hoyt
        Oct 4 '14 at 18:16











      • yes, this is how you can solve circular dependecies

        – Guru
        Oct 16 '14 at 4:41






      • 3





        What if you have a template method? Then you can't really move it into a CPP file unless you instantiate the templates manually.

        – Malcolm
        Sep 1 '16 at 12:55











      • You always include "A.h" and "B.h" together. Why don't you include "A.h" in "B.h" and then include only "B.h" in both "A.cpp" and "B.cpp"?

        – Gusev Slava
        Sep 30 '18 at 4:25



















      • Thanks. This solved the problem easily. I simply moved the circular includes to the .cpp files.

        – Lenar Hoyt
        Oct 4 '14 at 18:16











      • yes, this is how you can solve circular dependecies

        – Guru
        Oct 16 '14 at 4:41






      • 3





        What if you have a template method? Then you can't really move it into a CPP file unless you instantiate the templates manually.

        – Malcolm
        Sep 1 '16 at 12:55











      • You always include "A.h" and "B.h" together. Why don't you include "A.h" in "B.h" and then include only "B.h" in both "A.cpp" and "B.cpp"?

        – Gusev Slava
        Sep 30 '18 at 4:25

















      Thanks. This solved the problem easily. I simply moved the circular includes to the .cpp files.

      – Lenar Hoyt
      Oct 4 '14 at 18:16





      Thanks. This solved the problem easily. I simply moved the circular includes to the .cpp files.

      – Lenar Hoyt
      Oct 4 '14 at 18:16













      yes, this is how you can solve circular dependecies

      – Guru
      Oct 16 '14 at 4:41





      yes, this is how you can solve circular dependecies

      – Guru
      Oct 16 '14 at 4:41




      3




      3





      What if you have a template method? Then you can't really move it into a CPP file unless you instantiate the templates manually.

      – Malcolm
      Sep 1 '16 at 12:55





      What if you have a template method? Then you can't really move it into a CPP file unless you instantiate the templates manually.

      – Malcolm
      Sep 1 '16 at 12:55













      You always include "A.h" and "B.h" together. Why don't you include "A.h" in "B.h" and then include only "B.h" in both "A.cpp" and "B.cpp"?

      – Gusev Slava
      Sep 30 '18 at 4:25





      You always include "A.h" and "B.h" together. Why don't you include "A.h" in "B.h" and then include only "B.h" in both "A.cpp" and "B.cpp"?

      – Gusev Slava
      Sep 30 '18 at 4:25











      17














      Things to remember:




      • This won't work if class A has an object of class B as a member or vice versa.

      • Forward declaration is way to go.

      • Order of declaration matters (which is why you are moving out the definitions).


        • If both classes call functions of the other, you have to move the definitions out.




      Read the FAQ:




      • How can I create two classes that both know about each other?

      • What special considerations are needed when forward declarations are used with member objects?

      • What special considerations are needed when forward declarations are used with inline functions?






      share|improve this answer





















      • 1





        the links you provided dont work anymore, do you happen to know the new ones to refer to?

        – Ramya Rao
        Feb 22 '17 at 22:11
















      17














      Things to remember:




      • This won't work if class A has an object of class B as a member or vice versa.

      • Forward declaration is way to go.

      • Order of declaration matters (which is why you are moving out the definitions).


        • If both classes call functions of the other, you have to move the definitions out.




      Read the FAQ:




      • How can I create two classes that both know about each other?

      • What special considerations are needed when forward declarations are used with member objects?

      • What special considerations are needed when forward declarations are used with inline functions?






      share|improve this answer





















      • 1





        the links you provided dont work anymore, do you happen to know the new ones to refer to?

        – Ramya Rao
        Feb 22 '17 at 22:11














      17












      17








      17







      Things to remember:




      • This won't work if class A has an object of class B as a member or vice versa.

      • Forward declaration is way to go.

      • Order of declaration matters (which is why you are moving out the definitions).


        • If both classes call functions of the other, you have to move the definitions out.




      Read the FAQ:




      • How can I create two classes that both know about each other?

      • What special considerations are needed when forward declarations are used with member objects?

      • What special considerations are needed when forward declarations are used with inline functions?






      share|improve this answer















      Things to remember:




      • This won't work if class A has an object of class B as a member or vice versa.

      • Forward declaration is way to go.

      • Order of declaration matters (which is why you are moving out the definitions).


        • If both classes call functions of the other, you have to move the definitions out.




      Read the FAQ:




      • How can I create two classes that both know about each other?

      • What special considerations are needed when forward declarations are used with member objects?

      • What special considerations are needed when forward declarations are used with inline functions?







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Mar 1 '18 at 0:05









      Ken Y-N

      7,784134571




      7,784134571










      answered Mar 9 '09 at 11:07









      dirkgentlydirkgently

      90.6k15110176




      90.6k15110176








      • 1





        the links you provided dont work anymore, do you happen to know the new ones to refer to?

        – Ramya Rao
        Feb 22 '17 at 22:11














      • 1





        the links you provided dont work anymore, do you happen to know the new ones to refer to?

        – Ramya Rao
        Feb 22 '17 at 22:11








      1




      1





      the links you provided dont work anymore, do you happen to know the new ones to refer to?

      – Ramya Rao
      Feb 22 '17 at 22:11





      the links you provided dont work anymore, do you happen to know the new ones to refer to?

      – Ramya Rao
      Feb 22 '17 at 22:11











      13














      I'm late answering this, but there's not one reasonable answer to date, despite being a popular question with highly upvoted answers....



      Best practice: forward declaration headers



      As illustrated by the Standard library's <iosfwd> header, the proper way to provide forward declarations for others is to have a forward declaration header. For example:



      a.fwd.h:



      #pragma once
      class A;


      a.h:



      #pragma once
      #include "a.fwd.h"
      #include "b.fwd.h"

      class A
      {
      public:
      void f(B*);
      };


      b.fwd.h:



      #pragma once
      class B;


      b.h:



      #pragma once
      #include "b.fwd.h"
      #include "a.fwd.h"

      class B
      {
      public:
      void f(A*);
      };


      The maintainers of the A and B libraries should each be responsible for keeping their forward declaration headers in sync with their headers and implementation files, so - for example - if the maintainer of "B" comes along and rewrites the code to be...



      b.fwd.h:



      template <typename T> class Basic_B;
      typedef Basic_B<char> B;


      b.h:



      template <typename T>
      class Basic_B
      {
      ...class definition...
      };
      typedef Basic_B<char> B;


      ...then recompilation of the code for "A" will be triggered by the changes to the included b.fwd.h and should complete cleanly.





      Poor but common practice: forward declare stuff in other libs



      Say - instead of using a forward declaration header as explained above - code in a.h or a.cc instead forward-declares class B; itself:




      • if a.h or a.cc did include b.h later:


        • compilation of A will terminate with an error once it gets to the conflicting declaration/definition of B (i.e. the above change to B broke A and any other clients abusing forward declarations, instead of working transparently).



      • otherwise (if A didn't eventually include b.h - possible if A just stores/passes around Bs by pointer and/or reference)


        • build tools relying on #include analysis and changed file timestamps won't rebuild A (and its further-dependent code) after the change to B, causing errors at link time or run time. If B is distributed as a runtime loaded DLL, code in "A" may fail to find the differently-mangled symbols at runtime, which may or may not be handled well enough to trigger orderly shutdown or acceptably reduced functionality.




      If A's code has template specialisations / "traits" for the old B, they won't take effect.






      share|improve this answer





















      • 1





        This is a really clean way to handle the forward declarations. The only "disadvantage" would be in the extra files. I assume you always include a.fwd.h in a.h, to assure they stay in sync. The example code is missing where these classes are used. a.h and b.h will both need to be included since they won't function in isolation: ``` //main.cpp #include "a.h" #include "b.h" int main() { ... } ``` Or one of them needs to be fully included in the other like in the opening question. Where b.h includes a.h and main.cpp includes b.h

        – Farway
        May 5 '17 at 16:37








      • 2





        @Farway Right on all counts. I didn't bother showing main.cpp, but nice that you've documented what it should contain in your comment. Cheers

        – Tony Delroy
        May 5 '17 at 20:42






      • 1





        One of the better answers with a nice detailed explanation of why with the does and don'ts due to the pros and cons...

        – Francis Cugler
        Jan 16 '18 at 5:06






      • 1





        @RezaHajianpour: it makes sense to have a forward declaration header for all classes that you want forward declarations of, circular or not. That said, you will only want them when: 1) including the actual declaration is (or can be anticipated to later become) costly (e.g. it includes a lot of headers your translation unit might not otherwise need), and 2) client code is likely to be able to make use of pointers or references to the objects. <iosfwd> is a classic example: there can be a few stream objects referenced from many places, and <iostream> is a lot to include.

        – Tony Delroy
        Jan 23 at 5:02






      • 1





        @RezaHajianpour: I think you have the right idea, but there's a terminological issue with your statement: "we just need the type to be declared" would be right. The type being declared means the forward declaration has been seen; it's defined once the full definition has been parsed (and for that you may need more #includes).

        – Tony Delroy
        Jan 25 at 14:45


















      13














      I'm late answering this, but there's not one reasonable answer to date, despite being a popular question with highly upvoted answers....



      Best practice: forward declaration headers



      As illustrated by the Standard library's <iosfwd> header, the proper way to provide forward declarations for others is to have a forward declaration header. For example:



      a.fwd.h:



      #pragma once
      class A;


      a.h:



      #pragma once
      #include "a.fwd.h"
      #include "b.fwd.h"

      class A
      {
      public:
      void f(B*);
      };


      b.fwd.h:



      #pragma once
      class B;


      b.h:



      #pragma once
      #include "b.fwd.h"
      #include "a.fwd.h"

      class B
      {
      public:
      void f(A*);
      };


      The maintainers of the A and B libraries should each be responsible for keeping their forward declaration headers in sync with their headers and implementation files, so - for example - if the maintainer of "B" comes along and rewrites the code to be...



      b.fwd.h:



      template <typename T> class Basic_B;
      typedef Basic_B<char> B;


      b.h:



      template <typename T>
      class Basic_B
      {
      ...class definition...
      };
      typedef Basic_B<char> B;


      ...then recompilation of the code for "A" will be triggered by the changes to the included b.fwd.h and should complete cleanly.





      Poor but common practice: forward declare stuff in other libs



      Say - instead of using a forward declaration header as explained above - code in a.h or a.cc instead forward-declares class B; itself:




      • if a.h or a.cc did include b.h later:


        • compilation of A will terminate with an error once it gets to the conflicting declaration/definition of B (i.e. the above change to B broke A and any other clients abusing forward declarations, instead of working transparently).



      • otherwise (if A didn't eventually include b.h - possible if A just stores/passes around Bs by pointer and/or reference)


        • build tools relying on #include analysis and changed file timestamps won't rebuild A (and its further-dependent code) after the change to B, causing errors at link time or run time. If B is distributed as a runtime loaded DLL, code in "A" may fail to find the differently-mangled symbols at runtime, which may or may not be handled well enough to trigger orderly shutdown or acceptably reduced functionality.




      If A's code has template specialisations / "traits" for the old B, they won't take effect.






      share|improve this answer





















      • 1





        This is a really clean way to handle the forward declarations. The only "disadvantage" would be in the extra files. I assume you always include a.fwd.h in a.h, to assure they stay in sync. The example code is missing where these classes are used. a.h and b.h will both need to be included since they won't function in isolation: ``` //main.cpp #include "a.h" #include "b.h" int main() { ... } ``` Or one of them needs to be fully included in the other like in the opening question. Where b.h includes a.h and main.cpp includes b.h

        – Farway
        May 5 '17 at 16:37








      • 2





        @Farway Right on all counts. I didn't bother showing main.cpp, but nice that you've documented what it should contain in your comment. Cheers

        – Tony Delroy
        May 5 '17 at 20:42






      • 1





        One of the better answers with a nice detailed explanation of why with the does and don'ts due to the pros and cons...

        – Francis Cugler
        Jan 16 '18 at 5:06






      • 1





        @RezaHajianpour: it makes sense to have a forward declaration header for all classes that you want forward declarations of, circular or not. That said, you will only want them when: 1) including the actual declaration is (or can be anticipated to later become) costly (e.g. it includes a lot of headers your translation unit might not otherwise need), and 2) client code is likely to be able to make use of pointers or references to the objects. <iosfwd> is a classic example: there can be a few stream objects referenced from many places, and <iostream> is a lot to include.

        – Tony Delroy
        Jan 23 at 5:02






      • 1





        @RezaHajianpour: I think you have the right idea, but there's a terminological issue with your statement: "we just need the type to be declared" would be right. The type being declared means the forward declaration has been seen; it's defined once the full definition has been parsed (and for that you may need more #includes).

        – Tony Delroy
        Jan 25 at 14:45
















      13












      13








      13







      I'm late answering this, but there's not one reasonable answer to date, despite being a popular question with highly upvoted answers....



      Best practice: forward declaration headers



      As illustrated by the Standard library's <iosfwd> header, the proper way to provide forward declarations for others is to have a forward declaration header. For example:



      a.fwd.h:



      #pragma once
      class A;


      a.h:



      #pragma once
      #include "a.fwd.h"
      #include "b.fwd.h"

      class A
      {
      public:
      void f(B*);
      };


      b.fwd.h:



      #pragma once
      class B;


      b.h:



      #pragma once
      #include "b.fwd.h"
      #include "a.fwd.h"

      class B
      {
      public:
      void f(A*);
      };


      The maintainers of the A and B libraries should each be responsible for keeping their forward declaration headers in sync with their headers and implementation files, so - for example - if the maintainer of "B" comes along and rewrites the code to be...



      b.fwd.h:



      template <typename T> class Basic_B;
      typedef Basic_B<char> B;


      b.h:



      template <typename T>
      class Basic_B
      {
      ...class definition...
      };
      typedef Basic_B<char> B;


      ...then recompilation of the code for "A" will be triggered by the changes to the included b.fwd.h and should complete cleanly.





      Poor but common practice: forward declare stuff in other libs



      Say - instead of using a forward declaration header as explained above - code in a.h or a.cc instead forward-declares class B; itself:




      • if a.h or a.cc did include b.h later:


        • compilation of A will terminate with an error once it gets to the conflicting declaration/definition of B (i.e. the above change to B broke A and any other clients abusing forward declarations, instead of working transparently).



      • otherwise (if A didn't eventually include b.h - possible if A just stores/passes around Bs by pointer and/or reference)


        • build tools relying on #include analysis and changed file timestamps won't rebuild A (and its further-dependent code) after the change to B, causing errors at link time or run time. If B is distributed as a runtime loaded DLL, code in "A" may fail to find the differently-mangled symbols at runtime, which may or may not be handled well enough to trigger orderly shutdown or acceptably reduced functionality.




      If A's code has template specialisations / "traits" for the old B, they won't take effect.






      share|improve this answer















      I'm late answering this, but there's not one reasonable answer to date, despite being a popular question with highly upvoted answers....



      Best practice: forward declaration headers



      As illustrated by the Standard library's <iosfwd> header, the proper way to provide forward declarations for others is to have a forward declaration header. For example:



      a.fwd.h:



      #pragma once
      class A;


      a.h:



      #pragma once
      #include "a.fwd.h"
      #include "b.fwd.h"

      class A
      {
      public:
      void f(B*);
      };


      b.fwd.h:



      #pragma once
      class B;


      b.h:



      #pragma once
      #include "b.fwd.h"
      #include "a.fwd.h"

      class B
      {
      public:
      void f(A*);
      };


      The maintainers of the A and B libraries should each be responsible for keeping their forward declaration headers in sync with their headers and implementation files, so - for example - if the maintainer of "B" comes along and rewrites the code to be...



      b.fwd.h:



      template <typename T> class Basic_B;
      typedef Basic_B<char> B;


      b.h:



      template <typename T>
      class Basic_B
      {
      ...class definition...
      };
      typedef Basic_B<char> B;


      ...then recompilation of the code for "A" will be triggered by the changes to the included b.fwd.h and should complete cleanly.





      Poor but common practice: forward declare stuff in other libs



      Say - instead of using a forward declaration header as explained above - code in a.h or a.cc instead forward-declares class B; itself:




      • if a.h or a.cc did include b.h later:


        • compilation of A will terminate with an error once it gets to the conflicting declaration/definition of B (i.e. the above change to B broke A and any other clients abusing forward declarations, instead of working transparently).



      • otherwise (if A didn't eventually include b.h - possible if A just stores/passes around Bs by pointer and/or reference)


        • build tools relying on #include analysis and changed file timestamps won't rebuild A (and its further-dependent code) after the change to B, causing errors at link time or run time. If B is distributed as a runtime loaded DLL, code in "A" may fail to find the differently-mangled symbols at runtime, which may or may not be handled well enough to trigger orderly shutdown or acceptably reduced functionality.




      If A's code has template specialisations / "traits" for the old B, they won't take effect.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Jul 5 '16 at 12:56

























      answered Mar 23 '15 at 11:53









      Tony DelroyTony Delroy

      83.7k10128190




      83.7k10128190








      • 1





        This is a really clean way to handle the forward declarations. The only "disadvantage" would be in the extra files. I assume you always include a.fwd.h in a.h, to assure they stay in sync. The example code is missing where these classes are used. a.h and b.h will both need to be included since they won't function in isolation: ``` //main.cpp #include "a.h" #include "b.h" int main() { ... } ``` Or one of them needs to be fully included in the other like in the opening question. Where b.h includes a.h and main.cpp includes b.h

        – Farway
        May 5 '17 at 16:37








      • 2





        @Farway Right on all counts. I didn't bother showing main.cpp, but nice that you've documented what it should contain in your comment. Cheers

        – Tony Delroy
        May 5 '17 at 20:42






      • 1





        One of the better answers with a nice detailed explanation of why with the does and don'ts due to the pros and cons...

        – Francis Cugler
        Jan 16 '18 at 5:06






      • 1





        @RezaHajianpour: it makes sense to have a forward declaration header for all classes that you want forward declarations of, circular or not. That said, you will only want them when: 1) including the actual declaration is (or can be anticipated to later become) costly (e.g. it includes a lot of headers your translation unit might not otherwise need), and 2) client code is likely to be able to make use of pointers or references to the objects. <iosfwd> is a classic example: there can be a few stream objects referenced from many places, and <iostream> is a lot to include.

        – Tony Delroy
        Jan 23 at 5:02






      • 1





        @RezaHajianpour: I think you have the right idea, but there's a terminological issue with your statement: "we just need the type to be declared" would be right. The type being declared means the forward declaration has been seen; it's defined once the full definition has been parsed (and for that you may need more #includes).

        – Tony Delroy
        Jan 25 at 14:45
















      • 1





        This is a really clean way to handle the forward declarations. The only "disadvantage" would be in the extra files. I assume you always include a.fwd.h in a.h, to assure they stay in sync. The example code is missing where these classes are used. a.h and b.h will both need to be included since they won't function in isolation: ``` //main.cpp #include "a.h" #include "b.h" int main() { ... } ``` Or one of them needs to be fully included in the other like in the opening question. Where b.h includes a.h and main.cpp includes b.h

        – Farway
        May 5 '17 at 16:37








      • 2





        @Farway Right on all counts. I didn't bother showing main.cpp, but nice that you've documented what it should contain in your comment. Cheers

        – Tony Delroy
        May 5 '17 at 20:42






      • 1





        One of the better answers with a nice detailed explanation of why with the does and don'ts due to the pros and cons...

        – Francis Cugler
        Jan 16 '18 at 5:06






      • 1





        @RezaHajianpour: it makes sense to have a forward declaration header for all classes that you want forward declarations of, circular or not. That said, you will only want them when: 1) including the actual declaration is (or can be anticipated to later become) costly (e.g. it includes a lot of headers your translation unit might not otherwise need), and 2) client code is likely to be able to make use of pointers or references to the objects. <iosfwd> is a classic example: there can be a few stream objects referenced from many places, and <iostream> is a lot to include.

        – Tony Delroy
        Jan 23 at 5:02






      • 1





        @RezaHajianpour: I think you have the right idea, but there's a terminological issue with your statement: "we just need the type to be declared" would be right. The type being declared means the forward declaration has been seen; it's defined once the full definition has been parsed (and for that you may need more #includes).

        – Tony Delroy
        Jan 25 at 14:45










      1




      1





      This is a really clean way to handle the forward declarations. The only "disadvantage" would be in the extra files. I assume you always include a.fwd.h in a.h, to assure they stay in sync. The example code is missing where these classes are used. a.h and b.h will both need to be included since they won't function in isolation: ``` //main.cpp #include "a.h" #include "b.h" int main() { ... } ``` Or one of them needs to be fully included in the other like in the opening question. Where b.h includes a.h and main.cpp includes b.h

      – Farway
      May 5 '17 at 16:37







      This is a really clean way to handle the forward declarations. The only "disadvantage" would be in the extra files. I assume you always include a.fwd.h in a.h, to assure they stay in sync. The example code is missing where these classes are used. a.h and b.h will both need to be included since they won't function in isolation: ``` //main.cpp #include "a.h" #include "b.h" int main() { ... } ``` Or one of them needs to be fully included in the other like in the opening question. Where b.h includes a.h and main.cpp includes b.h

      – Farway
      May 5 '17 at 16:37






      2




      2





      @Farway Right on all counts. I didn't bother showing main.cpp, but nice that you've documented what it should contain in your comment. Cheers

      – Tony Delroy
      May 5 '17 at 20:42





      @Farway Right on all counts. I didn't bother showing main.cpp, but nice that you've documented what it should contain in your comment. Cheers

      – Tony Delroy
      May 5 '17 at 20:42




      1




      1





      One of the better answers with a nice detailed explanation of why with the does and don'ts due to the pros and cons...

      – Francis Cugler
      Jan 16 '18 at 5:06





      One of the better answers with a nice detailed explanation of why with the does and don'ts due to the pros and cons...

      – Francis Cugler
      Jan 16 '18 at 5:06




      1




      1





      @RezaHajianpour: it makes sense to have a forward declaration header for all classes that you want forward declarations of, circular or not. That said, you will only want them when: 1) including the actual declaration is (or can be anticipated to later become) costly (e.g. it includes a lot of headers your translation unit might not otherwise need), and 2) client code is likely to be able to make use of pointers or references to the objects. <iosfwd> is a classic example: there can be a few stream objects referenced from many places, and <iostream> is a lot to include.

      – Tony Delroy
      Jan 23 at 5:02





      @RezaHajianpour: it makes sense to have a forward declaration header for all classes that you want forward declarations of, circular or not. That said, you will only want them when: 1) including the actual declaration is (or can be anticipated to later become) costly (e.g. it includes a lot of headers your translation unit might not otherwise need), and 2) client code is likely to be able to make use of pointers or references to the objects. <iosfwd> is a classic example: there can be a few stream objects referenced from many places, and <iostream> is a lot to include.

      – Tony Delroy
      Jan 23 at 5:02




      1




      1





      @RezaHajianpour: I think you have the right idea, but there's a terminological issue with your statement: "we just need the type to be declared" would be right. The type being declared means the forward declaration has been seen; it's defined once the full definition has been parsed (and for that you may need more #includes).

      – Tony Delroy
      Jan 25 at 14:45







      @RezaHajianpour: I think you have the right idea, but there's a terminological issue with your statement: "we just need the type to be declared" would be right. The type being declared means the forward declaration has been seen; it's defined once the full definition has been parsed (and for that you may need more #includes).

      – Tony Delroy
      Jan 25 at 14:45













      11














      I once solved this kind of problem by moving all inlines after the class definition and putting the #include for the other classes just before the inlines in the header file. This way one make sure all definitions+inlines are set prior the inlines are parsed.



      Doing like this makes it possible to still have a bunch of inlines in both(or multiple) header files. But it's necessary to have include guards.



      Like this



      // File: A.h
      #ifndef __A_H__
      #define __A_H__
      class B;
      class A
      {
      int _val;
      B *_b;
      public:
      A(int val);
      void SetB(B *b);
      void Print();
      };

      // Including class B for inline usage here
      #include "B.h"

      inline A::A(int val) : _val(val)
      {
      }

      inline void A::SetB(B *b)
      {
      _b = b;
      _b->Print();
      }

      inline void A::Print()
      {
      cout<<"Type:A val="<<_val<<endl;
      }

      #endif /* __A_H__ */


      ...and doing the same in B.h






      share|improve this answer


























      • Why? I think it's an elegant solution to a tricky problem...when one wants inlines. If one don't want inlines one shouldn't have written the code like it was written from start...

        – epatel
        Mar 10 '09 at 20:01











      • What happens if a user includes B.h first?

        – Mr Fooz
        Mar 18 '14 at 16:00






      • 3





        Note that your header guard is using a reserved identifier, anything with double adjacent underscores is reserved.

        – Lars Viklund
        Aug 10 '15 at 15:09
















      11














      I once solved this kind of problem by moving all inlines after the class definition and putting the #include for the other classes just before the inlines in the header file. This way one make sure all definitions+inlines are set prior the inlines are parsed.



      Doing like this makes it possible to still have a bunch of inlines in both(or multiple) header files. But it's necessary to have include guards.



      Like this



      // File: A.h
      #ifndef __A_H__
      #define __A_H__
      class B;
      class A
      {
      int _val;
      B *_b;
      public:
      A(int val);
      void SetB(B *b);
      void Print();
      };

      // Including class B for inline usage here
      #include "B.h"

      inline A::A(int val) : _val(val)
      {
      }

      inline void A::SetB(B *b)
      {
      _b = b;
      _b->Print();
      }

      inline void A::Print()
      {
      cout<<"Type:A val="<<_val<<endl;
      }

      #endif /* __A_H__ */


      ...and doing the same in B.h






      share|improve this answer


























      • Why? I think it's an elegant solution to a tricky problem...when one wants inlines. If one don't want inlines one shouldn't have written the code like it was written from start...

        – epatel
        Mar 10 '09 at 20:01











      • What happens if a user includes B.h first?

        – Mr Fooz
        Mar 18 '14 at 16:00






      • 3





        Note that your header guard is using a reserved identifier, anything with double adjacent underscores is reserved.

        – Lars Viklund
        Aug 10 '15 at 15:09














      11












      11








      11







      I once solved this kind of problem by moving all inlines after the class definition and putting the #include for the other classes just before the inlines in the header file. This way one make sure all definitions+inlines are set prior the inlines are parsed.



      Doing like this makes it possible to still have a bunch of inlines in both(or multiple) header files. But it's necessary to have include guards.



      Like this



      // File: A.h
      #ifndef __A_H__
      #define __A_H__
      class B;
      class A
      {
      int _val;
      B *_b;
      public:
      A(int val);
      void SetB(B *b);
      void Print();
      };

      // Including class B for inline usage here
      #include "B.h"

      inline A::A(int val) : _val(val)
      {
      }

      inline void A::SetB(B *b)
      {
      _b = b;
      _b->Print();
      }

      inline void A::Print()
      {
      cout<<"Type:A val="<<_val<<endl;
      }

      #endif /* __A_H__ */


      ...and doing the same in B.h






      share|improve this answer















      I once solved this kind of problem by moving all inlines after the class definition and putting the #include for the other classes just before the inlines in the header file. This way one make sure all definitions+inlines are set prior the inlines are parsed.



      Doing like this makes it possible to still have a bunch of inlines in both(or multiple) header files. But it's necessary to have include guards.



      Like this



      // File: A.h
      #ifndef __A_H__
      #define __A_H__
      class B;
      class A
      {
      int _val;
      B *_b;
      public:
      A(int val);
      void SetB(B *b);
      void Print();
      };

      // Including class B for inline usage here
      #include "B.h"

      inline A::A(int val) : _val(val)
      {
      }

      inline void A::SetB(B *b)
      {
      _b = b;
      _b->Print();
      }

      inline void A::Print()
      {
      cout<<"Type:A val="<<_val<<endl;
      }

      #endif /* __A_H__ */


      ...and doing the same in B.h







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Mar 10 '09 at 0:18

























      answered Mar 9 '09 at 21:25









      epatelepatel

      42.4k1698137




      42.4k1698137













      • Why? I think it's an elegant solution to a tricky problem...when one wants inlines. If one don't want inlines one shouldn't have written the code like it was written from start...

        – epatel
        Mar 10 '09 at 20:01











      • What happens if a user includes B.h first?

        – Mr Fooz
        Mar 18 '14 at 16:00






      • 3





        Note that your header guard is using a reserved identifier, anything with double adjacent underscores is reserved.

        – Lars Viklund
        Aug 10 '15 at 15:09



















      • Why? I think it's an elegant solution to a tricky problem...when one wants inlines. If one don't want inlines one shouldn't have written the code like it was written from start...

        – epatel
        Mar 10 '09 at 20:01











      • What happens if a user includes B.h first?

        – Mr Fooz
        Mar 18 '14 at 16:00






      • 3





        Note that your header guard is using a reserved identifier, anything with double adjacent underscores is reserved.

        – Lars Viklund
        Aug 10 '15 at 15:09

















      Why? I think it's an elegant solution to a tricky problem...when one wants inlines. If one don't want inlines one shouldn't have written the code like it was written from start...

      – epatel
      Mar 10 '09 at 20:01





      Why? I think it's an elegant solution to a tricky problem...when one wants inlines. If one don't want inlines one shouldn't have written the code like it was written from start...

      – epatel
      Mar 10 '09 at 20:01













      What happens if a user includes B.h first?

      – Mr Fooz
      Mar 18 '14 at 16:00





      What happens if a user includes B.h first?

      – Mr Fooz
      Mar 18 '14 at 16:00




      3




      3





      Note that your header guard is using a reserved identifier, anything with double adjacent underscores is reserved.

      – Lars Viklund
      Aug 10 '15 at 15:09





      Note that your header guard is using a reserved identifier, anything with double adjacent underscores is reserved.

      – Lars Viklund
      Aug 10 '15 at 15:09











      6














      I've written a post about this once: Resolving circular dependencies in c++



      The basic technique is to decouple the classes using interfaces. So in your case:



      //Printer.h
      class Printer {
      public:
      virtual Print() = 0;
      }

      //A.h
      #include "Printer.h"
      class A: public Printer
      {
      int _val;
      Printer *_b;
      public:

      A(int val)
      :_val(val)
      {
      }

      void SetB(Printer *b)
      {
      _b = b;
      _b->Print();
      }

      void Print()
      {
      cout<<"Type:A val="<<_val<<endl;
      }
      };

      //B.h
      #include "Printer.h"
      class B: public Printer
      {
      double _val;
      Printer* _a;
      public:

      B(double val)
      :_val(val)
      {
      }

      void SetA(Printer *a)
      {
      _a = a;
      _a->Print();
      }

      void Print()
      {
      cout<<"Type:B val="<<_val<<endl;
      }
      };

      //main.cpp
      #include <iostream>
      #include "A.h"
      #include "B.h"

      int main(int argc, char* argv)
      {
      A a(10);
      B b(3.14);
      a.Print();
      a.SetB(&b);
      b.Print();
      b.SetA(&a);
      return 0;
      }





      share|improve this answer





















      • 2





        Please note that use of interfaces and virtual has runtime performance impacts.

        – cemper93
        Jun 22 '16 at 19:10
















      6














      I've written a post about this once: Resolving circular dependencies in c++



      The basic technique is to decouple the classes using interfaces. So in your case:



      //Printer.h
      class Printer {
      public:
      virtual Print() = 0;
      }

      //A.h
      #include "Printer.h"
      class A: public Printer
      {
      int _val;
      Printer *_b;
      public:

      A(int val)
      :_val(val)
      {
      }

      void SetB(Printer *b)
      {
      _b = b;
      _b->Print();
      }

      void Print()
      {
      cout<<"Type:A val="<<_val<<endl;
      }
      };

      //B.h
      #include "Printer.h"
      class B: public Printer
      {
      double _val;
      Printer* _a;
      public:

      B(double val)
      :_val(val)
      {
      }

      void SetA(Printer *a)
      {
      _a = a;
      _a->Print();
      }

      void Print()
      {
      cout<<"Type:B val="<<_val<<endl;
      }
      };

      //main.cpp
      #include <iostream>
      #include "A.h"
      #include "B.h"

      int main(int argc, char* argv)
      {
      A a(10);
      B b(3.14);
      a.Print();
      a.SetB(&b);
      b.Print();
      b.SetA(&a);
      return 0;
      }





      share|improve this answer





















      • 2





        Please note that use of interfaces and virtual has runtime performance impacts.

        – cemper93
        Jun 22 '16 at 19:10














      6












      6








      6







      I've written a post about this once: Resolving circular dependencies in c++



      The basic technique is to decouple the classes using interfaces. So in your case:



      //Printer.h
      class Printer {
      public:
      virtual Print() = 0;
      }

      //A.h
      #include "Printer.h"
      class A: public Printer
      {
      int _val;
      Printer *_b;
      public:

      A(int val)
      :_val(val)
      {
      }

      void SetB(Printer *b)
      {
      _b = b;
      _b->Print();
      }

      void Print()
      {
      cout<<"Type:A val="<<_val<<endl;
      }
      };

      //B.h
      #include "Printer.h"
      class B: public Printer
      {
      double _val;
      Printer* _a;
      public:

      B(double val)
      :_val(val)
      {
      }

      void SetA(Printer *a)
      {
      _a = a;
      _a->Print();
      }

      void Print()
      {
      cout<<"Type:B val="<<_val<<endl;
      }
      };

      //main.cpp
      #include <iostream>
      #include "A.h"
      #include "B.h"

      int main(int argc, char* argv)
      {
      A a(10);
      B b(3.14);
      a.Print();
      a.SetB(&b);
      b.Print();
      b.SetA(&a);
      return 0;
      }





      share|improve this answer















      I've written a post about this once: Resolving circular dependencies in c++



      The basic technique is to decouple the classes using interfaces. So in your case:



      //Printer.h
      class Printer {
      public:
      virtual Print() = 0;
      }

      //A.h
      #include "Printer.h"
      class A: public Printer
      {
      int _val;
      Printer *_b;
      public:

      A(int val)
      :_val(val)
      {
      }

      void SetB(Printer *b)
      {
      _b = b;
      _b->Print();
      }

      void Print()
      {
      cout<<"Type:A val="<<_val<<endl;
      }
      };

      //B.h
      #include "Printer.h"
      class B: public Printer
      {
      double _val;
      Printer* _a;
      public:

      B(double val)
      :_val(val)
      {
      }

      void SetA(Printer *a)
      {
      _a = a;
      _a->Print();
      }

      void Print()
      {
      cout<<"Type:B val="<<_val<<endl;
      }
      };

      //main.cpp
      #include <iostream>
      #include "A.h"
      #include "B.h"

      int main(int argc, char* argv)
      {
      A a(10);
      B b(3.14);
      a.Print();
      a.SetB(&b);
      b.Print();
      b.SetA(&a);
      return 0;
      }






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Apr 5 '15 at 20:31

























      answered Dec 15 '13 at 18:12









      Eduard WirchEduard Wirch

      7,45375165




      7,45375165








      • 2





        Please note that use of interfaces and virtual has runtime performance impacts.

        – cemper93
        Jun 22 '16 at 19:10














      • 2





        Please note that use of interfaces and virtual has runtime performance impacts.

        – cemper93
        Jun 22 '16 at 19:10








      2




      2





      Please note that use of interfaces and virtual has runtime performance impacts.

      – cemper93
      Jun 22 '16 at 19:10





      Please note that use of interfaces and virtual has runtime performance impacts.

      – cemper93
      Jun 22 '16 at 19:10











      3














      Here is the solution for templates: How to handle circular dependencies with templates



      The clue to solving this problem is to declare both classes before providing the definitions (implementations). It’s not possible to split the declaration and definition into separate files, but you can structure them as if they were in separate files.






      share|improve this answer






























        3














        Here is the solution for templates: How to handle circular dependencies with templates



        The clue to solving this problem is to declare both classes before providing the definitions (implementations). It’s not possible to split the declaration and definition into separate files, but you can structure them as if they were in separate files.






        share|improve this answer




























          3












          3








          3







          Here is the solution for templates: How to handle circular dependencies with templates



          The clue to solving this problem is to declare both classes before providing the definitions (implementations). It’s not possible to split the declaration and definition into separate files, but you can structure them as if they were in separate files.






          share|improve this answer















          Here is the solution for templates: How to handle circular dependencies with templates



          The clue to solving this problem is to declare both classes before providing the definitions (implementations). It’s not possible to split the declaration and definition into separate files, but you can structure them as if they were in separate files.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Jan 1 '16 at 12:43

























          answered Oct 9 '15 at 21:21









          TatyanaTatyana

          473




          473























              2














              The simple example presented on Wikipedia worked for me.
              (you can read the complete description at http://en.wikipedia.org/wiki/Circular_dependency#Example_of_circular_dependencies_in_C.2B.2B )



              File '''a.h''':



              #ifndef A_H
              #define A_H

              class B; //forward declaration

              class A {
              public:
              B* b;
              };
              #endif //A_H


              File '''b.h''':



              #ifndef B_H
              #define B_H

              class A; //forward declaration

              class B {
              public:
              A* a;
              };
              #endif //B_H


              File '''main.cpp''':



              #include "a.h"
              #include "b.h"

              int main() {
              A a;
              B b;
              a.b = &b;
              b.a = &a;
              }





              share|improve this answer






























                2














                The simple example presented on Wikipedia worked for me.
                (you can read the complete description at http://en.wikipedia.org/wiki/Circular_dependency#Example_of_circular_dependencies_in_C.2B.2B )



                File '''a.h''':



                #ifndef A_H
                #define A_H

                class B; //forward declaration

                class A {
                public:
                B* b;
                };
                #endif //A_H


                File '''b.h''':



                #ifndef B_H
                #define B_H

                class A; //forward declaration

                class B {
                public:
                A* a;
                };
                #endif //B_H


                File '''main.cpp''':



                #include "a.h"
                #include "b.h"

                int main() {
                A a;
                B b;
                a.b = &b;
                b.a = &a;
                }





                share|improve this answer




























                  2












                  2








                  2







                  The simple example presented on Wikipedia worked for me.
                  (you can read the complete description at http://en.wikipedia.org/wiki/Circular_dependency#Example_of_circular_dependencies_in_C.2B.2B )



                  File '''a.h''':



                  #ifndef A_H
                  #define A_H

                  class B; //forward declaration

                  class A {
                  public:
                  B* b;
                  };
                  #endif //A_H


                  File '''b.h''':



                  #ifndef B_H
                  #define B_H

                  class A; //forward declaration

                  class B {
                  public:
                  A* a;
                  };
                  #endif //B_H


                  File '''main.cpp''':



                  #include "a.h"
                  #include "b.h"

                  int main() {
                  A a;
                  B b;
                  a.b = &b;
                  b.a = &a;
                  }





                  share|improve this answer















                  The simple example presented on Wikipedia worked for me.
                  (you can read the complete description at http://en.wikipedia.org/wiki/Circular_dependency#Example_of_circular_dependencies_in_C.2B.2B )



                  File '''a.h''':



                  #ifndef A_H
                  #define A_H

                  class B; //forward declaration

                  class A {
                  public:
                  B* b;
                  };
                  #endif //A_H


                  File '''b.h''':



                  #ifndef B_H
                  #define B_H

                  class A; //forward declaration

                  class B {
                  public:
                  A* a;
                  };
                  #endif //B_H


                  File '''main.cpp''':



                  #include "a.h"
                  #include "b.h"

                  int main() {
                  A a;
                  B b;
                  a.b = &b;
                  b.a = &a;
                  }






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Dec 10 '14 at 17:32

























                  answered Dec 10 '14 at 16:48









                  madxmadx

                  4,00423645




                  4,00423645























                      0














                      Unfortunately, all the previous answers are missing some details. The correct solution is a little bit cumbersome, but this is the only way to do it properly. And it scales easily, handles more complex dependencies as well.



                      Here's how you can do this, exactly retaining all the details, and usability:




                      • the solution is exactly the same as originally intended

                      • inline functions still inline

                      • users of A and B can include A.h and B.h in any order


                      Create two files, A_def.h, B_def.h. These will contain only A's and B's definition:



                      // A_def.h
                      #ifndef A_DEF_H
                      #define A_DEF_H

                      class B;
                      class A
                      {
                      int _val;
                      B *_b;

                      public:
                      A(int val);
                      void SetB(B *b);
                      void Print();
                      };
                      #endif

                      // B_def.h
                      #ifndef B_DEF_H
                      #define B_DEF_H

                      class A;
                      class B
                      {
                      double _val;
                      A* _a;

                      public:
                      B(double val);
                      void SetA(A *a);
                      void Print();
                      };
                      #endif


                      And then, A.h and B.h will contain this:



                      // A.h
                      #ifndef A_H
                      #define A_H

                      #include "A_def.h"
                      #include "B_def.h"

                      inline A::A(int val) :_val(val)
                      {
                      }

                      inline void A::SetB(B *b)
                      {
                      _b = b;
                      _b->Print();
                      }

                      inline void A::Print()
                      {
                      cout<<"Type:A val="<<_val<<endl;
                      }

                      #endif

                      // B.h
                      #ifndef B_H
                      #define B_H

                      #include "A_def.h"
                      #include "B_def.h"

                      inline B::B(double val) :_val(val)
                      {
                      }

                      inline void B::SetA(A *a)
                      {
                      _a = a;
                      _a->Print();
                      }

                      inline void B::Print()
                      {
                      cout<<"Type:B val="<<_val<<endl;
                      }

                      #endif


                      Note that A_def.h and B_def.h are "private" headers, users of A and B should not use them. The public header is A.h and B.h.






                      share|improve this answer
























                      • Does this have any advantages over Tony Delroy's solution? Both are based on "helper" headers, but Tony's are smaller (they just contain the forward declaration) and they seem to be working the same way (at least at first glance).

                        – Fabio Turati
                        Nov 20 '18 at 11:33











                      • That answer doesn't solve the original problem. It just says "put forward declarations into a separate header". Nothing about resolving circular dependency (the question needs a solution where A's and B's definition is available, forward declaration is not enough).

                        – geza
                        Nov 20 '18 at 11:50
















                      0














                      Unfortunately, all the previous answers are missing some details. The correct solution is a little bit cumbersome, but this is the only way to do it properly. And it scales easily, handles more complex dependencies as well.



                      Here's how you can do this, exactly retaining all the details, and usability:




                      • the solution is exactly the same as originally intended

                      • inline functions still inline

                      • users of A and B can include A.h and B.h in any order


                      Create two files, A_def.h, B_def.h. These will contain only A's and B's definition:



                      // A_def.h
                      #ifndef A_DEF_H
                      #define A_DEF_H

                      class B;
                      class A
                      {
                      int _val;
                      B *_b;

                      public:
                      A(int val);
                      void SetB(B *b);
                      void Print();
                      };
                      #endif

                      // B_def.h
                      #ifndef B_DEF_H
                      #define B_DEF_H

                      class A;
                      class B
                      {
                      double _val;
                      A* _a;

                      public:
                      B(double val);
                      void SetA(A *a);
                      void Print();
                      };
                      #endif


                      And then, A.h and B.h will contain this:



                      // A.h
                      #ifndef A_H
                      #define A_H

                      #include "A_def.h"
                      #include "B_def.h"

                      inline A::A(int val) :_val(val)
                      {
                      }

                      inline void A::SetB(B *b)
                      {
                      _b = b;
                      _b->Print();
                      }

                      inline void A::Print()
                      {
                      cout<<"Type:A val="<<_val<<endl;
                      }

                      #endif

                      // B.h
                      #ifndef B_H
                      #define B_H

                      #include "A_def.h"
                      #include "B_def.h"

                      inline B::B(double val) :_val(val)
                      {
                      }

                      inline void B::SetA(A *a)
                      {
                      _a = a;
                      _a->Print();
                      }

                      inline void B::Print()
                      {
                      cout<<"Type:B val="<<_val<<endl;
                      }

                      #endif


                      Note that A_def.h and B_def.h are "private" headers, users of A and B should not use them. The public header is A.h and B.h.






                      share|improve this answer
























                      • Does this have any advantages over Tony Delroy's solution? Both are based on "helper" headers, but Tony's are smaller (they just contain the forward declaration) and they seem to be working the same way (at least at first glance).

                        – Fabio Turati
                        Nov 20 '18 at 11:33











                      • That answer doesn't solve the original problem. It just says "put forward declarations into a separate header". Nothing about resolving circular dependency (the question needs a solution where A's and B's definition is available, forward declaration is not enough).

                        – geza
                        Nov 20 '18 at 11:50














                      0












                      0








                      0







                      Unfortunately, all the previous answers are missing some details. The correct solution is a little bit cumbersome, but this is the only way to do it properly. And it scales easily, handles more complex dependencies as well.



                      Here's how you can do this, exactly retaining all the details, and usability:




                      • the solution is exactly the same as originally intended

                      • inline functions still inline

                      • users of A and B can include A.h and B.h in any order


                      Create two files, A_def.h, B_def.h. These will contain only A's and B's definition:



                      // A_def.h
                      #ifndef A_DEF_H
                      #define A_DEF_H

                      class B;
                      class A
                      {
                      int _val;
                      B *_b;

                      public:
                      A(int val);
                      void SetB(B *b);
                      void Print();
                      };
                      #endif

                      // B_def.h
                      #ifndef B_DEF_H
                      #define B_DEF_H

                      class A;
                      class B
                      {
                      double _val;
                      A* _a;

                      public:
                      B(double val);
                      void SetA(A *a);
                      void Print();
                      };
                      #endif


                      And then, A.h and B.h will contain this:



                      // A.h
                      #ifndef A_H
                      #define A_H

                      #include "A_def.h"
                      #include "B_def.h"

                      inline A::A(int val) :_val(val)
                      {
                      }

                      inline void A::SetB(B *b)
                      {
                      _b = b;
                      _b->Print();
                      }

                      inline void A::Print()
                      {
                      cout<<"Type:A val="<<_val<<endl;
                      }

                      #endif

                      // B.h
                      #ifndef B_H
                      #define B_H

                      #include "A_def.h"
                      #include "B_def.h"

                      inline B::B(double val) :_val(val)
                      {
                      }

                      inline void B::SetA(A *a)
                      {
                      _a = a;
                      _a->Print();
                      }

                      inline void B::Print()
                      {
                      cout<<"Type:B val="<<_val<<endl;
                      }

                      #endif


                      Note that A_def.h and B_def.h are "private" headers, users of A and B should not use them. The public header is A.h and B.h.






                      share|improve this answer













                      Unfortunately, all the previous answers are missing some details. The correct solution is a little bit cumbersome, but this is the only way to do it properly. And it scales easily, handles more complex dependencies as well.



                      Here's how you can do this, exactly retaining all the details, and usability:




                      • the solution is exactly the same as originally intended

                      • inline functions still inline

                      • users of A and B can include A.h and B.h in any order


                      Create two files, A_def.h, B_def.h. These will contain only A's and B's definition:



                      // A_def.h
                      #ifndef A_DEF_H
                      #define A_DEF_H

                      class B;
                      class A
                      {
                      int _val;
                      B *_b;

                      public:
                      A(int val);
                      void SetB(B *b);
                      void Print();
                      };
                      #endif

                      // B_def.h
                      #ifndef B_DEF_H
                      #define B_DEF_H

                      class A;
                      class B
                      {
                      double _val;
                      A* _a;

                      public:
                      B(double val);
                      void SetA(A *a);
                      void Print();
                      };
                      #endif


                      And then, A.h and B.h will contain this:



                      // A.h
                      #ifndef A_H
                      #define A_H

                      #include "A_def.h"
                      #include "B_def.h"

                      inline A::A(int val) :_val(val)
                      {
                      }

                      inline void A::SetB(B *b)
                      {
                      _b = b;
                      _b->Print();
                      }

                      inline void A::Print()
                      {
                      cout<<"Type:A val="<<_val<<endl;
                      }

                      #endif

                      // B.h
                      #ifndef B_H
                      #define B_H

                      #include "A_def.h"
                      #include "B_def.h"

                      inline B::B(double val) :_val(val)
                      {
                      }

                      inline void B::SetA(A *a)
                      {
                      _a = a;
                      _a->Print();
                      }

                      inline void B::Print()
                      {
                      cout<<"Type:B val="<<_val<<endl;
                      }

                      #endif


                      Note that A_def.h and B_def.h are "private" headers, users of A and B should not use them. The public header is A.h and B.h.







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Jul 5 '18 at 7:02









                      gezageza

                      12.9k32776




                      12.9k32776













                      • Does this have any advantages over Tony Delroy's solution? Both are based on "helper" headers, but Tony's are smaller (they just contain the forward declaration) and they seem to be working the same way (at least at first glance).

                        – Fabio Turati
                        Nov 20 '18 at 11:33











                      • That answer doesn't solve the original problem. It just says "put forward declarations into a separate header". Nothing about resolving circular dependency (the question needs a solution where A's and B's definition is available, forward declaration is not enough).

                        – geza
                        Nov 20 '18 at 11:50



















                      • Does this have any advantages over Tony Delroy's solution? Both are based on "helper" headers, but Tony's are smaller (they just contain the forward declaration) and they seem to be working the same way (at least at first glance).

                        – Fabio Turati
                        Nov 20 '18 at 11:33











                      • That answer doesn't solve the original problem. It just says "put forward declarations into a separate header". Nothing about resolving circular dependency (the question needs a solution where A's and B's definition is available, forward declaration is not enough).

                        – geza
                        Nov 20 '18 at 11:50

















                      Does this have any advantages over Tony Delroy's solution? Both are based on "helper" headers, but Tony's are smaller (they just contain the forward declaration) and they seem to be working the same way (at least at first glance).

                      – Fabio Turati
                      Nov 20 '18 at 11:33





                      Does this have any advantages over Tony Delroy's solution? Both are based on "helper" headers, but Tony's are smaller (they just contain the forward declaration) and they seem to be working the same way (at least at first glance).

                      – Fabio Turati
                      Nov 20 '18 at 11:33













                      That answer doesn't solve the original problem. It just says "put forward declarations into a separate header". Nothing about resolving circular dependency (the question needs a solution where A's and B's definition is available, forward declaration is not enough).

                      – geza
                      Nov 20 '18 at 11:50





                      That answer doesn't solve the original problem. It just says "put forward declarations into a separate header". Nothing about resolving circular dependency (the question needs a solution where A's and B's definition is available, forward declaration is not enough).

                      – geza
                      Nov 20 '18 at 11:50





                      protected by StoryTeller Oct 12 '17 at 14:13



                      Thank you for your interest in this question.
                      Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



                      Would you like to answer one of these unanswered questions instead?



                      Popular posts from this blog

                      Feedback on college project

                      Futebolista

                      Albești (Vaslui)