forward declaration with vector of class type - pointer to incomplete class type not allowed











up vote
9
down vote

favorite
2












I have two classes, foo and bar.



foo.h #includes bar.h and contains a std::vector of pointers to bar objects. At some point during runtime, bar has to access this vector of pointers to other bar objects. Therefore, foo contains a method named getBarObjects() that returns the array of pointers.



Therefore, I forward declare foo in bar.h. I obviously also have to forward declare the method I'm using - foo::getBarObjects(). As this returns the array of pointers to bar, I get into a vicious cycle.



I cannot forward declare Bar and then simply forward declare getBarObjects(), as this results in "incomplete type name is not allowed".



foo.h:



#include "bar.h"
#include <vector>

class foo {
public:
foo();
~foo();
std::vector<bar*> getBarObjects();
private:
std::vector<bar*> barObjects;
}


bar.h:



class foo;
std::vector<bar*> foo::getBarObjects(); // error, doesn't know bar at this point

class bar {
public:
bar(foo *currentFoo);
~bar();
bool dosth();
private:
foo *thisFoo;
}


bar.cpp:



#include "bar.h"

bool bar(foo *currentFoo) {
thisFoo = currentFoo;
}

bool bar::dosth() {
thisFoo->getBarObjects(); // error, pointer to inomplete class type is not allowed
}


If I simply include the other way around, I'll have just the same problem in foo later on. Any suggestions?










share|improve this question




























    up vote
    9
    down vote

    favorite
    2












    I have two classes, foo and bar.



    foo.h #includes bar.h and contains a std::vector of pointers to bar objects. At some point during runtime, bar has to access this vector of pointers to other bar objects. Therefore, foo contains a method named getBarObjects() that returns the array of pointers.



    Therefore, I forward declare foo in bar.h. I obviously also have to forward declare the method I'm using - foo::getBarObjects(). As this returns the array of pointers to bar, I get into a vicious cycle.



    I cannot forward declare Bar and then simply forward declare getBarObjects(), as this results in "incomplete type name is not allowed".



    foo.h:



    #include "bar.h"
    #include <vector>

    class foo {
    public:
    foo();
    ~foo();
    std::vector<bar*> getBarObjects();
    private:
    std::vector<bar*> barObjects;
    }


    bar.h:



    class foo;
    std::vector<bar*> foo::getBarObjects(); // error, doesn't know bar at this point

    class bar {
    public:
    bar(foo *currentFoo);
    ~bar();
    bool dosth();
    private:
    foo *thisFoo;
    }


    bar.cpp:



    #include "bar.h"

    bool bar(foo *currentFoo) {
    thisFoo = currentFoo;
    }

    bool bar::dosth() {
    thisFoo->getBarObjects(); // error, pointer to inomplete class type is not allowed
    }


    If I simply include the other way around, I'll have just the same problem in foo later on. Any suggestions?










    share|improve this question


























      up vote
      9
      down vote

      favorite
      2









      up vote
      9
      down vote

      favorite
      2






      2





      I have two classes, foo and bar.



      foo.h #includes bar.h and contains a std::vector of pointers to bar objects. At some point during runtime, bar has to access this vector of pointers to other bar objects. Therefore, foo contains a method named getBarObjects() that returns the array of pointers.



      Therefore, I forward declare foo in bar.h. I obviously also have to forward declare the method I'm using - foo::getBarObjects(). As this returns the array of pointers to bar, I get into a vicious cycle.



      I cannot forward declare Bar and then simply forward declare getBarObjects(), as this results in "incomplete type name is not allowed".



      foo.h:



      #include "bar.h"
      #include <vector>

      class foo {
      public:
      foo();
      ~foo();
      std::vector<bar*> getBarObjects();
      private:
      std::vector<bar*> barObjects;
      }


      bar.h:



      class foo;
      std::vector<bar*> foo::getBarObjects(); // error, doesn't know bar at this point

      class bar {
      public:
      bar(foo *currentFoo);
      ~bar();
      bool dosth();
      private:
      foo *thisFoo;
      }


      bar.cpp:



      #include "bar.h"

      bool bar(foo *currentFoo) {
      thisFoo = currentFoo;
      }

      bool bar::dosth() {
      thisFoo->getBarObjects(); // error, pointer to inomplete class type is not allowed
      }


      If I simply include the other way around, I'll have just the same problem in foo later on. Any suggestions?










      share|improve this question















      I have two classes, foo and bar.



      foo.h #includes bar.h and contains a std::vector of pointers to bar objects. At some point during runtime, bar has to access this vector of pointers to other bar objects. Therefore, foo contains a method named getBarObjects() that returns the array of pointers.



      Therefore, I forward declare foo in bar.h. I obviously also have to forward declare the method I'm using - foo::getBarObjects(). As this returns the array of pointers to bar, I get into a vicious cycle.



      I cannot forward declare Bar and then simply forward declare getBarObjects(), as this results in "incomplete type name is not allowed".



      foo.h:



      #include "bar.h"
      #include <vector>

      class foo {
      public:
      foo();
      ~foo();
      std::vector<bar*> getBarObjects();
      private:
      std::vector<bar*> barObjects;
      }


      bar.h:



      class foo;
      std::vector<bar*> foo::getBarObjects(); // error, doesn't know bar at this point

      class bar {
      public:
      bar(foo *currentFoo);
      ~bar();
      bool dosth();
      private:
      foo *thisFoo;
      }


      bar.cpp:



      #include "bar.h"

      bool bar(foo *currentFoo) {
      thisFoo = currentFoo;
      }

      bool bar::dosth() {
      thisFoo->getBarObjects(); // error, pointer to inomplete class type is not allowed
      }


      If I simply include the other way around, I'll have just the same problem in foo later on. Any suggestions?







      c++ circular-dependency forward-declaration






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 20 at 17:13









      Fabio Turati

      2,54752138




      2,54752138










      asked Oct 10 '11 at 14:35









      Aerius

      349418




      349418
























          3 Answers
          3






          active

          oldest

          votes

















          up vote
          19
          down vote



          accepted










          You can't forward declare members.



          Instead, bar.cpp should #include both foo.h and bar.h. Problem solved.



          In general, if you use the sequence:




          • Forward declare all class types

          • Define all class types

          • Bodies of class members


          everything will be fine.






          share|improve this answer





















          • Meh, simple solution to a problem that seemed big. Thank you!
            – Aerius
            Oct 10 '11 at 15:14










          • I have been looking for this solution for hours. Thank you!
            – tcallred
            Aug 17 at 4:13


















          up vote
          6
          down vote













          You don't have to include foo.h or bar.h from each other unless you're accessing the internals of either class from the other header file. Declare the classes as needed in the header files, then include both header files from your source file.



          foo.h



          #include <vector>
          class bar;
          class foo {
          public:
          foo();
          ~foo();
          std::vector<bar*> getBarObjects();
          private:
          std::vector<bar*> barObjects;
          };


          bar.h



          class foo;
          class bar {
          public:
          bar(foo *currentFoo);
          ~bar();
          bool dosth();
          private:
          foo *thisFoo;
          }


          bar.cpp



          #include "foo.h"
          #include "bar.h"

          bool bar(foo *currentFoo) {
          thisFoo = currentFoo;
          }

          bool bar::dosth() {
          thisFoo->getBarObjects();
          }





          share|improve this answer




























            up vote
            1
            down vote













            You forgot to forward declare the vector in foo.h. You also return the vector by-value from getBarObjects which is possibly not what you want and the forward declaration of the member function is useless.



            Also: Use header guards. Prefer the appropriate smart pointer for your situation (std::shared_ptr, unique_ptr) over raw pointers. Watch out for constness.






            share|improve this answer























            • I used header guards, no worries, I just let them out here as I typed all that to avoid confusion with additional classnames and whatnot. Thanks though
              – Aerius
              Oct 10 '11 at 14:40











            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f7714345%2fforward-declaration-with-vector-of-class-type-pointer-to-incomplete-class-type%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            19
            down vote



            accepted










            You can't forward declare members.



            Instead, bar.cpp should #include both foo.h and bar.h. Problem solved.



            In general, if you use the sequence:




            • Forward declare all class types

            • Define all class types

            • Bodies of class members


            everything will be fine.






            share|improve this answer





















            • Meh, simple solution to a problem that seemed big. Thank you!
              – Aerius
              Oct 10 '11 at 15:14










            • I have been looking for this solution for hours. Thank you!
              – tcallred
              Aug 17 at 4:13















            up vote
            19
            down vote



            accepted










            You can't forward declare members.



            Instead, bar.cpp should #include both foo.h and bar.h. Problem solved.



            In general, if you use the sequence:




            • Forward declare all class types

            • Define all class types

            • Bodies of class members


            everything will be fine.






            share|improve this answer





















            • Meh, simple solution to a problem that seemed big. Thank you!
              – Aerius
              Oct 10 '11 at 15:14










            • I have been looking for this solution for hours. Thank you!
              – tcallred
              Aug 17 at 4:13













            up vote
            19
            down vote



            accepted







            up vote
            19
            down vote



            accepted






            You can't forward declare members.



            Instead, bar.cpp should #include both foo.h and bar.h. Problem solved.



            In general, if you use the sequence:




            • Forward declare all class types

            • Define all class types

            • Bodies of class members


            everything will be fine.






            share|improve this answer












            You can't forward declare members.



            Instead, bar.cpp should #include both foo.h and bar.h. Problem solved.



            In general, if you use the sequence:




            • Forward declare all class types

            • Define all class types

            • Bodies of class members


            everything will be fine.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Oct 10 '11 at 14:37









            Ben Voigt

            233k29308563




            233k29308563












            • Meh, simple solution to a problem that seemed big. Thank you!
              – Aerius
              Oct 10 '11 at 15:14










            • I have been looking for this solution for hours. Thank you!
              – tcallred
              Aug 17 at 4:13


















            • Meh, simple solution to a problem that seemed big. Thank you!
              – Aerius
              Oct 10 '11 at 15:14










            • I have been looking for this solution for hours. Thank you!
              – tcallred
              Aug 17 at 4:13
















            Meh, simple solution to a problem that seemed big. Thank you!
            – Aerius
            Oct 10 '11 at 15:14




            Meh, simple solution to a problem that seemed big. Thank you!
            – Aerius
            Oct 10 '11 at 15:14












            I have been looking for this solution for hours. Thank you!
            – tcallred
            Aug 17 at 4:13




            I have been looking for this solution for hours. Thank you!
            – tcallred
            Aug 17 at 4:13












            up vote
            6
            down vote













            You don't have to include foo.h or bar.h from each other unless you're accessing the internals of either class from the other header file. Declare the classes as needed in the header files, then include both header files from your source file.



            foo.h



            #include <vector>
            class bar;
            class foo {
            public:
            foo();
            ~foo();
            std::vector<bar*> getBarObjects();
            private:
            std::vector<bar*> barObjects;
            };


            bar.h



            class foo;
            class bar {
            public:
            bar(foo *currentFoo);
            ~bar();
            bool dosth();
            private:
            foo *thisFoo;
            }


            bar.cpp



            #include "foo.h"
            #include "bar.h"

            bool bar(foo *currentFoo) {
            thisFoo = currentFoo;
            }

            bool bar::dosth() {
            thisFoo->getBarObjects();
            }





            share|improve this answer

























              up vote
              6
              down vote













              You don't have to include foo.h or bar.h from each other unless you're accessing the internals of either class from the other header file. Declare the classes as needed in the header files, then include both header files from your source file.



              foo.h



              #include <vector>
              class bar;
              class foo {
              public:
              foo();
              ~foo();
              std::vector<bar*> getBarObjects();
              private:
              std::vector<bar*> barObjects;
              };


              bar.h



              class foo;
              class bar {
              public:
              bar(foo *currentFoo);
              ~bar();
              bool dosth();
              private:
              foo *thisFoo;
              }


              bar.cpp



              #include "foo.h"
              #include "bar.h"

              bool bar(foo *currentFoo) {
              thisFoo = currentFoo;
              }

              bool bar::dosth() {
              thisFoo->getBarObjects();
              }





              share|improve this answer























                up vote
                6
                down vote










                up vote
                6
                down vote









                You don't have to include foo.h or bar.h from each other unless you're accessing the internals of either class from the other header file. Declare the classes as needed in the header files, then include both header files from your source file.



                foo.h



                #include <vector>
                class bar;
                class foo {
                public:
                foo();
                ~foo();
                std::vector<bar*> getBarObjects();
                private:
                std::vector<bar*> barObjects;
                };


                bar.h



                class foo;
                class bar {
                public:
                bar(foo *currentFoo);
                ~bar();
                bool dosth();
                private:
                foo *thisFoo;
                }


                bar.cpp



                #include "foo.h"
                #include "bar.h"

                bool bar(foo *currentFoo) {
                thisFoo = currentFoo;
                }

                bool bar::dosth() {
                thisFoo->getBarObjects();
                }





                share|improve this answer












                You don't have to include foo.h or bar.h from each other unless you're accessing the internals of either class from the other header file. Declare the classes as needed in the header files, then include both header files from your source file.



                foo.h



                #include <vector>
                class bar;
                class foo {
                public:
                foo();
                ~foo();
                std::vector<bar*> getBarObjects();
                private:
                std::vector<bar*> barObjects;
                };


                bar.h



                class foo;
                class bar {
                public:
                bar(foo *currentFoo);
                ~bar();
                bool dosth();
                private:
                foo *thisFoo;
                }


                bar.cpp



                #include "foo.h"
                #include "bar.h"

                bool bar(foo *currentFoo) {
                thisFoo = currentFoo;
                }

                bool bar::dosth() {
                thisFoo->getBarObjects();
                }






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Oct 10 '11 at 14:51









                CurtisB

                1945




                1945






















                    up vote
                    1
                    down vote













                    You forgot to forward declare the vector in foo.h. You also return the vector by-value from getBarObjects which is possibly not what you want and the forward declaration of the member function is useless.



                    Also: Use header guards. Prefer the appropriate smart pointer for your situation (std::shared_ptr, unique_ptr) over raw pointers. Watch out for constness.






                    share|improve this answer























                    • I used header guards, no worries, I just let them out here as I typed all that to avoid confusion with additional classnames and whatnot. Thanks though
                      – Aerius
                      Oct 10 '11 at 14:40















                    up vote
                    1
                    down vote













                    You forgot to forward declare the vector in foo.h. You also return the vector by-value from getBarObjects which is possibly not what you want and the forward declaration of the member function is useless.



                    Also: Use header guards. Prefer the appropriate smart pointer for your situation (std::shared_ptr, unique_ptr) over raw pointers. Watch out for constness.






                    share|improve this answer























                    • I used header guards, no worries, I just let them out here as I typed all that to avoid confusion with additional classnames and whatnot. Thanks though
                      – Aerius
                      Oct 10 '11 at 14:40













                    up vote
                    1
                    down vote










                    up vote
                    1
                    down vote









                    You forgot to forward declare the vector in foo.h. You also return the vector by-value from getBarObjects which is possibly not what you want and the forward declaration of the member function is useless.



                    Also: Use header guards. Prefer the appropriate smart pointer for your situation (std::shared_ptr, unique_ptr) over raw pointers. Watch out for constness.






                    share|improve this answer














                    You forgot to forward declare the vector in foo.h. You also return the vector by-value from getBarObjects which is possibly not what you want and the forward declaration of the member function is useless.



                    Also: Use header guards. Prefer the appropriate smart pointer for your situation (std::shared_ptr, unique_ptr) over raw pointers. Watch out for constness.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Apr 11 '15 at 14:21

























                    answered Oct 10 '11 at 14:37









                    pmr

                    46.3k686137




                    46.3k686137












                    • I used header guards, no worries, I just let them out here as I typed all that to avoid confusion with additional classnames and whatnot. Thanks though
                      – Aerius
                      Oct 10 '11 at 14:40


















                    • I used header guards, no worries, I just let them out here as I typed all that to avoid confusion with additional classnames and whatnot. Thanks though
                      – Aerius
                      Oct 10 '11 at 14:40
















                    I used header guards, no worries, I just let them out here as I typed all that to avoid confusion with additional classnames and whatnot. Thanks though
                    – Aerius
                    Oct 10 '11 at 14:40




                    I used header guards, no worries, I just let them out here as I typed all that to avoid confusion with additional classnames and whatnot. Thanks though
                    – Aerius
                    Oct 10 '11 at 14:40


















                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f7714345%2fforward-declaration-with-vector-of-class-type-pointer-to-incomplete-class-type%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    404 Error Contact Form 7 ajax form submitting

                    How to know if a Active Directory user can login interactively

                    TypeError: fit_transform() missing 1 required positional argument: 'X'