简体   繁体   中英

C++ nested classes referencing each other

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

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.

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, ie:

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM