C++ nested classes referencing each other











up vote
2
down vote

favorite












In C# I can have two nested classes refer to each other without problem:



public class CFGFile
{
class Setting
{
public Entry Ent;
}

class Entry
{
public Setting Setg;
}
}


However, trying the same thing in C++ causes problems:



class CFGFile
{
class Setting;

class Entry
{
Setting Setg;
};

class Setting
{
Entry Ent;
]
};


I get




"incomplete type not allowed"




at the Setg variable definition, and error




"C2079: 'CFGFile::Entry::Setg' uses undefined class
'CFGFile::Setting'"




when compiling.



I'm using Visual Studio 2017.



Is cross referring not possible in nested classes in C++?










share|improve this question




















  • 3




    Try with struct instead of class in C#, this should be a fair comparison. Shouldn't work either.
    – tkausl
    Nov 21 at 14:27












  • @tkausl because in the C# example above, references to objects are being defined, not objects of the class types. I get it. Thanks!
    – L Fitz
    Nov 21 at 14:46










  • values cannot be NULL, so what you wrote is a Entry containing a Setting which in turn contains an Entry which again contains a Setting which in turn contains an Entry.... ad infinitum
    – user463035818
    Nov 21 at 15:02















up vote
2
down vote

favorite












In C# I can have two nested classes refer to each other without problem:



public class CFGFile
{
class Setting
{
public Entry Ent;
}

class Entry
{
public Setting Setg;
}
}


However, trying the same thing in C++ causes problems:



class CFGFile
{
class Setting;

class Entry
{
Setting Setg;
};

class Setting
{
Entry Ent;
]
};


I get




"incomplete type not allowed"




at the Setg variable definition, and error




"C2079: 'CFGFile::Entry::Setg' uses undefined class
'CFGFile::Setting'"




when compiling.



I'm using Visual Studio 2017.



Is cross referring not possible in nested classes in C++?










share|improve this question




















  • 3




    Try with struct instead of class in C#, this should be a fair comparison. Shouldn't work either.
    – tkausl
    Nov 21 at 14:27












  • @tkausl because in the C# example above, references to objects are being defined, not objects of the class types. I get it. Thanks!
    – L Fitz
    Nov 21 at 14:46










  • values cannot be NULL, so what you wrote is a Entry containing a Setting which in turn contains an Entry which again contains a Setting which in turn contains an Entry.... ad infinitum
    – user463035818
    Nov 21 at 15:02













up vote
2
down vote

favorite









up vote
2
down vote

favorite











In C# I can have two nested classes refer to each other without problem:



public class CFGFile
{
class Setting
{
public Entry Ent;
}

class Entry
{
public Setting Setg;
}
}


However, trying the same thing in C++ causes problems:



class CFGFile
{
class Setting;

class Entry
{
Setting Setg;
};

class Setting
{
Entry Ent;
]
};


I get




"incomplete type not allowed"




at the Setg variable definition, and error




"C2079: 'CFGFile::Entry::Setg' uses undefined class
'CFGFile::Setting'"




when compiling.



I'm using Visual Studio 2017.



Is cross referring not possible in nested classes in C++?










share|improve this question















In C# I can have two nested classes refer to each other without problem:



public class CFGFile
{
class Setting
{
public Entry Ent;
}

class Entry
{
public Setting Setg;
}
}


However, trying the same thing in C++ causes problems:



class CFGFile
{
class Setting;

class Entry
{
Setting Setg;
};

class Setting
{
Entry Ent;
]
};


I get




"incomplete type not allowed"




at the Setg variable definition, and error




"C2079: 'CFGFile::Entry::Setg' uses undefined class
'CFGFile::Setting'"




when compiling.



I'm using Visual Studio 2017.



Is cross referring not possible in nested classes in C++?







c++ class nested visual-studio-2017






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 21 at 15:23









Poul Bak

5,42831132




5,42831132










asked Nov 21 at 14:26









L Fitz

284




284








  • 3




    Try with struct instead of class in C#, this should be a fair comparison. Shouldn't work either.
    – tkausl
    Nov 21 at 14:27












  • @tkausl because in the C# example above, references to objects are being defined, not objects of the class types. I get it. Thanks!
    – L Fitz
    Nov 21 at 14:46










  • values cannot be NULL, so what you wrote is a Entry containing a Setting which in turn contains an Entry which again contains a Setting which in turn contains an Entry.... ad infinitum
    – user463035818
    Nov 21 at 15:02














  • 3




    Try with struct instead of class in C#, this should be a fair comparison. Shouldn't work either.
    – tkausl
    Nov 21 at 14:27












  • @tkausl because in the C# example above, references to objects are being defined, not objects of the class types. I get it. Thanks!
    – L Fitz
    Nov 21 at 14:46










  • values cannot be NULL, so what you wrote is a Entry containing a Setting which in turn contains an Entry which again contains a Setting which in turn contains an Entry.... ad infinitum
    – user463035818
    Nov 21 at 15:02








3




3




Try with struct instead of class in C#, this should be a fair comparison. Shouldn't work either.
– tkausl
Nov 21 at 14:27






Try with struct instead of class in C#, this should be a fair comparison. Shouldn't work either.
– tkausl
Nov 21 at 14:27














@tkausl because in the C# example above, references to objects are being defined, not objects of the class types. I get it. Thanks!
– L Fitz
Nov 21 at 14:46




@tkausl because in the C# example above, references to objects are being defined, not objects of the class types. I get it. Thanks!
– L Fitz
Nov 21 at 14:46












values cannot be NULL, so what you wrote is a Entry containing a Setting which in turn contains an Entry which again contains a Setting which in turn contains an Entry.... ad infinitum
– user463035818
Nov 21 at 15:02




values cannot be NULL, so what you wrote is a Entry containing a Setting which in turn contains an Entry which again contains a Setting which in turn contains an Entry.... ad infinitum
– user463035818
Nov 21 at 15:02












3 Answers
3






active

oldest

votes

















up vote
5
down vote



accepted










This has nothing to do with nested or not. In C++, you can not cross reference each other for two classes/structs like that. The workaround is that you use either pointer or reference which does not require a complete type definition. In your case, try the following,



class CFGFile
{
class Setting;

class Entry
{
Setting* Setg; // or std::unique_ptr<Setting> Setg;
};

class Setting
{
Entry Ent;
};
};


As suggested by @Ted Lyngmo, std::unique_ptr is the preferred way in modern C++ for applications.






share|improve this answer























  • Perhaps a suggestion to use std::unique_ptr<Setting> Setg; would be good.
    – Ted Lyngmo
    Nov 21 at 14:43












  • Using pointers for cross references. Thanks!
    – L Fitz
    Nov 21 at 14:46




















up vote
0
down vote













To expand on why this happens, this comes from the fact that when the compiler looks at a struct or class, it needs to be able to determine its exact size, among other things to be able to know how much memory it needs to allocate for instances of these.



In this case, the compiler can't determine the size of Entry because it only knows that a Setting class exists, but it doesn't know its size yet.



Using a pointer, i.e.:



class Setting;

class Entry
{
Setting* Setg;
};


actually solves this problem, because while the compiler still doesn't know anything about Setting, it still knows the size of a pointer (regardless of the pointee's type).



As already mentioned, the "nested" part has no impact on this.






share|improve this answer




























    up vote
    0
    down vote













    C# - by design - uses reference semantics for classes, thus the provided snippet does not cause circular value depency. OTH c++ prefers value semantics , which would -in turn- result in infinite recursion in the original sample code, if the standard did not ban that kind of code; As implicated in earlier replies, if reference semantics is needed, it should be explicitly expressed in terms of pointer/reference syntax.






    share|improve this answer





















      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',
      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%2f53414238%2fc-nested-classes-referencing-each-other%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
      5
      down vote



      accepted










      This has nothing to do with nested or not. In C++, you can not cross reference each other for two classes/structs like that. The workaround is that you use either pointer or reference which does not require a complete type definition. In your case, try the following,



      class CFGFile
      {
      class Setting;

      class Entry
      {
      Setting* Setg; // or std::unique_ptr<Setting> Setg;
      };

      class Setting
      {
      Entry Ent;
      };
      };


      As suggested by @Ted Lyngmo, std::unique_ptr is the preferred way in modern C++ for applications.






      share|improve this answer























      • Perhaps a suggestion to use std::unique_ptr<Setting> Setg; would be good.
        – Ted Lyngmo
        Nov 21 at 14:43












      • Using pointers for cross references. Thanks!
        – L Fitz
        Nov 21 at 14:46

















      up vote
      5
      down vote



      accepted










      This has nothing to do with nested or not. In C++, you can not cross reference each other for two classes/structs like that. The workaround is that you use either pointer or reference which does not require a complete type definition. In your case, try the following,



      class CFGFile
      {
      class Setting;

      class Entry
      {
      Setting* Setg; // or std::unique_ptr<Setting> Setg;
      };

      class Setting
      {
      Entry Ent;
      };
      };


      As suggested by @Ted Lyngmo, std::unique_ptr is the preferred way in modern C++ for applications.






      share|improve this answer























      • Perhaps a suggestion to use std::unique_ptr<Setting> Setg; would be good.
        – Ted Lyngmo
        Nov 21 at 14:43












      • Using pointers for cross references. Thanks!
        – L Fitz
        Nov 21 at 14:46















      up vote
      5
      down vote



      accepted







      up vote
      5
      down vote



      accepted






      This has nothing to do with nested or not. In C++, you can not cross reference each other for two classes/structs like that. The workaround is that you use either pointer or reference which does not require a complete type definition. In your case, try the following,



      class CFGFile
      {
      class Setting;

      class Entry
      {
      Setting* Setg; // or std::unique_ptr<Setting> Setg;
      };

      class Setting
      {
      Entry Ent;
      };
      };


      As suggested by @Ted Lyngmo, std::unique_ptr is the preferred way in modern C++ for applications.






      share|improve this answer














      This has nothing to do with nested or not. In C++, you can not cross reference each other for two classes/structs like that. The workaround is that you use either pointer or reference which does not require a complete type definition. In your case, try the following,



      class CFGFile
      {
      class Setting;

      class Entry
      {
      Setting* Setg; // or std::unique_ptr<Setting> Setg;
      };

      class Setting
      {
      Entry Ent;
      };
      };


      As suggested by @Ted Lyngmo, std::unique_ptr is the preferred way in modern C++ for applications.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Nov 21 at 14:50

























      answered Nov 21 at 14:31









      CS Pei

      8,1631938




      8,1631938












      • Perhaps a suggestion to use std::unique_ptr<Setting> Setg; would be good.
        – Ted Lyngmo
        Nov 21 at 14:43












      • Using pointers for cross references. Thanks!
        – L Fitz
        Nov 21 at 14:46




















      • Perhaps a suggestion to use std::unique_ptr<Setting> Setg; would be good.
        – Ted Lyngmo
        Nov 21 at 14:43












      • Using pointers for cross references. Thanks!
        – L Fitz
        Nov 21 at 14:46


















      Perhaps a suggestion to use std::unique_ptr<Setting> Setg; would be good.
      – Ted Lyngmo
      Nov 21 at 14:43






      Perhaps a suggestion to use std::unique_ptr<Setting> Setg; would be good.
      – Ted Lyngmo
      Nov 21 at 14:43














      Using pointers for cross references. Thanks!
      – L Fitz
      Nov 21 at 14:46






      Using pointers for cross references. Thanks!
      – L Fitz
      Nov 21 at 14:46














      up vote
      0
      down vote













      To expand on why this happens, this comes from the fact that when the compiler looks at a struct or class, it needs to be able to determine its exact size, among other things to be able to know how much memory it needs to allocate for instances of these.



      In this case, the compiler can't determine the size of Entry because it only knows that a Setting class exists, but it doesn't know its size yet.



      Using a pointer, i.e.:



      class Setting;

      class Entry
      {
      Setting* Setg;
      };


      actually solves this problem, because while the compiler still doesn't know anything about Setting, it still knows the size of a pointer (regardless of the pointee's type).



      As already mentioned, the "nested" part has no impact on this.






      share|improve this answer

























        up vote
        0
        down vote













        To expand on why this happens, this comes from the fact that when the compiler looks at a struct or class, it needs to be able to determine its exact size, among other things to be able to know how much memory it needs to allocate for instances of these.



        In this case, the compiler can't determine the size of Entry because it only knows that a Setting class exists, but it doesn't know its size yet.



        Using a pointer, i.e.:



        class Setting;

        class Entry
        {
        Setting* Setg;
        };


        actually solves this problem, because while the compiler still doesn't know anything about Setting, it still knows the size of a pointer (regardless of the pointee's type).



        As already mentioned, the "nested" part has no impact on this.






        share|improve this answer























          up vote
          0
          down vote










          up vote
          0
          down vote









          To expand on why this happens, this comes from the fact that when the compiler looks at a struct or class, it needs to be able to determine its exact size, among other things to be able to know how much memory it needs to allocate for instances of these.



          In this case, the compiler can't determine the size of Entry because it only knows that a Setting class exists, but it doesn't know its size yet.



          Using a pointer, i.e.:



          class Setting;

          class Entry
          {
          Setting* Setg;
          };


          actually solves this problem, because while the compiler still doesn't know anything about Setting, it still knows the size of a pointer (regardless of the pointee's type).



          As already mentioned, the "nested" part has no impact on this.






          share|improve this answer












          To expand on why this happens, this comes from the fact that when the compiler looks at a struct or class, it needs to be able to determine its exact size, among other things to be able to know how much memory it needs to allocate for instances of these.



          In this case, the compiler can't determine the size of Entry because it only knows that a Setting class exists, but it doesn't know its size yet.



          Using a pointer, i.e.:



          class Setting;

          class Entry
          {
          Setting* Setg;
          };


          actually solves this problem, because while the compiler still doesn't know anything about Setting, it still knows the size of a pointer (regardless of the pointee's type).



          As already mentioned, the "nested" part has no impact on this.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 21 at 14:56









          JBL

          9,65333667




          9,65333667






















              up vote
              0
              down vote













              C# - by design - uses reference semantics for classes, thus the provided snippet does not cause circular value depency. OTH c++ prefers value semantics , which would -in turn- result in infinite recursion in the original sample code, if the standard did not ban that kind of code; As implicated in earlier replies, if reference semantics is needed, it should be explicitly expressed in terms of pointer/reference syntax.






              share|improve this answer

























                up vote
                0
                down vote













                C# - by design - uses reference semantics for classes, thus the provided snippet does not cause circular value depency. OTH c++ prefers value semantics , which would -in turn- result in infinite recursion in the original sample code, if the standard did not ban that kind of code; As implicated in earlier replies, if reference semantics is needed, it should be explicitly expressed in terms of pointer/reference syntax.






                share|improve this answer























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  C# - by design - uses reference semantics for classes, thus the provided snippet does not cause circular value depency. OTH c++ prefers value semantics , which would -in turn- result in infinite recursion in the original sample code, if the standard did not ban that kind of code; As implicated in earlier replies, if reference semantics is needed, it should be explicitly expressed in terms of pointer/reference syntax.






                  share|improve this answer












                  C# - by design - uses reference semantics for classes, thus the provided snippet does not cause circular value depency. OTH c++ prefers value semantics , which would -in turn- result in infinite recursion in the original sample code, if the standard did not ban that kind of code; As implicated in earlier replies, if reference semantics is needed, it should be explicitly expressed in terms of pointer/reference syntax.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 21 at 15:29









                  Red.Wave

                  71937




                  71937






























                      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%2f53414238%2fc-nested-classes-referencing-each-other%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

                      Berounka

                      Sphinx de Gizeh

                      Different font size/position of beamer's navigation symbols template's content depending on regular/plain...