Resolve build errors due to circular dependency amongst classes











up vote
287
down vote

favorite
165












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.
    – wil
    Sep 12 '12 at 3:08






  • 2




    The above link appears to have moved. Here's the new link for /showIncludes on MSDN
    – Tas
    Oct 26 '17 at 4:30















up vote
287
down vote

favorite
165












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.
    – wil
    Sep 12 '12 at 3:08






  • 2




    The above link appears to have moved. Here's the new link for /showIncludes on MSDN
    – Tas
    Oct 26 '17 at 4:30













up vote
287
down vote

favorite
165









up vote
287
down vote

favorite
165






165





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

89.9k12180246




89.9k12180246










asked Mar 9 '09 at 10:57









Autodidact

16.5k135572




16.5k135572








  • 17




    When working with Visual Studio, the /showIncludes flag helps a lot to debug this kind of problems.
    – wil
    Sep 12 '12 at 3:08






  • 2




    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.
    – wil
    Sep 12 '12 at 3:08






  • 2




    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.
– wil
Sep 12 '12 at 3:08




When working with Visual Studio, the /showIncludes flag helps a lot to debug this kind of problems.
– wil
Sep 12 '12 at 3:08




2




2




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

















up vote
233
down vote



accepted










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



















  • 15




    "Telling the compiler about B" is known as a forward declaration of B.
    – Peter Ajtai
    Nov 17 '10 at 1:57






  • 6




    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






  • 30




    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


















up vote
93
down vote













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



















  • 8




    This is the best answer
    – rank1
    Apr 17 '13 at 15:26










  • 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 at 4:25


















up vote
17
down vote













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


















up vote
11
down vote













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


















up vote
11
down vote













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























  • 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










  • 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 at 5:06


















up vote
7
down vote













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


















up vote
3
down vote













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






























    up vote
    2
    down vote













    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






























      up vote
      0
      down vote













      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 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 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








      up vote
      233
      down vote



      accepted










      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



















      • 15




        "Telling the compiler about B" is known as a forward declaration of B.
        – Peter Ajtai
        Nov 17 '10 at 1:57






      • 6




        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






      • 30




        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















      up vote
      233
      down vote



      accepted










      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



















      • 15




        "Telling the compiler about B" is known as a forward declaration of B.
        – Peter Ajtai
        Nov 17 '10 at 1:57






      • 6




        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






      • 30




        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













      up vote
      233
      down vote



      accepted







      up vote
      233
      down vote



      accepted






      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









      Roosh

      2,3902112




      2,3902112








      • 15




        "Telling the compiler about B" is known as a forward declaration of B.
        – Peter Ajtai
        Nov 17 '10 at 1:57






      • 6




        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






      • 30




        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














      • 15




        "Telling the compiler about B" is known as a forward declaration of B.
        – Peter Ajtai
        Nov 17 '10 at 1:57






      • 6




        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






      • 30




        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








      15




      15




      "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




      6




      6




      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




      30




      30




      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












      up vote
      93
      down vote













      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



















      • 8




        This is the best answer
        – rank1
        Apr 17 '13 at 15:26










      • 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 at 4:25















      up vote
      93
      down vote













      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



















      • 8




        This is the best answer
        – rank1
        Apr 17 '13 at 15:26










      • 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 at 4:25













      up vote
      93
      down vote










      up vote
      93
      down vote









      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









      Autodidact

      16.5k135572




      16.5k135572








      • 8




        This is the best answer
        – rank1
        Apr 17 '13 at 15:26










      • 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 at 4:25














      • 8




        This is the best answer
        – rank1
        Apr 17 '13 at 15:26










      • 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 at 4:25








      8




      8




      This is the best answer
      – rank1
      Apr 17 '13 at 15:26




      This is the best answer
      – rank1
      Apr 17 '13 at 15:26












      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 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 at 4:25










      up vote
      17
      down vote













      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















      up vote
      17
      down vote













      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













      up vote
      17
      down vote










      up vote
      17
      down vote









      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 at 0:05









      Ken Y-N

      7,383134469




      7,383134469










      answered Mar 9 '09 at 11:07









      dirkgently

      89.5k15110176




      89.5k15110176








      • 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










      up vote
      11
      down vote













      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















      up vote
      11
      down vote













      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













      up vote
      11
      down vote










      up vote
      11
      down vote









      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









      epatel

      42.2k1698136




      42.2k1698136












      • 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










      up vote
      11
      down vote













      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























      • 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










      • 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 at 5:06















      up vote
      11
      down vote













      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























      • 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










      • 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 at 5:06













      up vote
      11
      down vote










      up vote
      11
      down vote









      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 Delroy

      82.8k9124186




      82.8k9124186












      • 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










      • 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 at 5:06


















      • 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










      • 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 at 5:06
















      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












      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 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 at 5:06










      up vote
      7
      down vote













      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















      up vote
      7
      down vote













      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













      up vote
      7
      down vote










      up vote
      7
      down vote









      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 Wirch

      7,33575065




      7,33575065








      • 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










      up vote
      3
      down vote













      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



























        up vote
        3
        down vote













        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

























          up vote
          3
          down vote










          up vote
          3
          down vote









          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









          Tatyana

          513




          513






















              up vote
              2
              down vote













              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



























                up vote
                2
                down vote













                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

























                  up vote
                  2
                  down vote










                  up vote
                  2
                  down vote









                  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









                  madx

                  3,86823344




                  3,86823344






















                      up vote
                      0
                      down vote













                      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 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 at 11:50















                      up vote
                      0
                      down vote













                      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 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 at 11:50













                      up vote
                      0
                      down vote










                      up vote
                      0
                      down vote









                      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 at 7:02









                      geza

                      11.8k32771




                      11.8k32771












                      • 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 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 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 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 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 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 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 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 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

                      Guess what letter conforming each word

                      Port of Spain

                      Run scheduled task as local user group (not BUILTIN)