C++ nested classes referencing each other












2














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 '18 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 '18 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 '18 at 15:02
















2














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 '18 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 '18 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 '18 at 15:02














2












2








2







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 '18 at 15:23









Poul Bak

5,43331232




5,43331232










asked Nov 21 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 at 14:27






Try with struct instead of class in C#, this should be a fair comparison. Shouldn't work either.
– tkausl
Nov 21 '18 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 '18 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 '18 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 '18 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 '18 at 15:02












3 Answers
3






active

oldest

votes


















5














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 '18 at 14:43












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





















0














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





























    0














    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',
      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%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









      5














      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 '18 at 14:43












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


















      5














      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 '18 at 14:43












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
















      5












      5








      5






      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 '18 at 14:50

























      answered Nov 21 '18 at 14:31









      CS Pei

      8,3801938




      8,3801938












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












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




















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












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


















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






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














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






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















      0














      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


























        0














        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
























          0












          0








          0






          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 '18 at 14:56









          JBL

          9,70333667




          9,70333667























              0














              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


























                0














                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
























                  0












                  0








                  0






                  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 '18 at 15:29









                  Red.Wave

                  72737




                  72737






























                      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

                      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'