C ++ вложенные классы, ссылающиеся друг на друга - PullRequest
0 голосов
/ 21 ноября 2018

В C # я могу иметь два вложенных класса, без проблем ссылающихся друг на друга:

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

  class Entry
  {
    public Setting Setg;
  }
}

Однако попытка того же самого в C ++ вызывает проблемы:

class CFGFile
{
  class Setting;

  class Entry
  {
    Setting Setg;
  };

  class Setting
  {
    Entry Ent;
  ]
};

Я получаю

«неполный тип не разрешен»

при определении переменной Setg и ошибка

»C2079: 'CFGFile :: Entry ::Setg 'использует неопределенный класс' CFGFile :: Setting '"

при компиляции.

Я использую Visual Studio 2017.

Перекрестные ссылки невозможны ввложенные классы в C ++?

Ответы [ 3 ]

0 голосов
/ 21 ноября 2018

Чтобы объяснить, почему это происходит, это происходит из-за того, что когда компилятор смотрит на структуру или класс, он должен иметь возможность определить его точный размер, среди прочего, чтобы знать, сколько памяти ему нужновыделить для экземпляров этих.

В этом случае компилятор не может определить размер Entry, потому что он знает только, что существует класс Setting, но еще не знает его размер.

Использование указателя, то есть:

class Setting;

class Entry
{
    Setting* Setg;
};

фактически решает эту проблему, потому что, хотя компилятор все еще ничего не знает о Setting, он все же знает размер указателя(независимо от типа получателя).

Как уже упоминалось, «вложенная» часть на это не влияет.

0 голосов
/ 21 ноября 2018

C # - по замыслу - использует ссылочную семантику для классов, поэтому предоставленный фрагмент не вызывает циклическую зависимость значения.OTH c ++ предпочитает семантику значений, которая, в свою очередь, приведет к бесконечной рекурсии в исходном образце кода, если стандарт не запрещает такой код;Как указывалось в предыдущих ответах, если необходима ссылочная семантика, она должна быть явно выражена в терминах синтаксиса указатель / ссылка.

0 голосов
/ 21 ноября 2018

Это не имеет ничего общего с nested или нет.В C ++ вы не можете перекрестно ссылаться друг на друга для двух таких классов / структур.Обходной путь заключается в том, что вы используете либо указатель, либо ссылку, которая не требует полного определения типа.В вашем случае попробуйте следующее:

class CFGFile
{
  class Setting;

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

  class Setting
  {
    Entry Ent;
  };
};

Как подсказывает @Ted Lyngmo, std::unique_ptr является предпочтительным способом в современном C ++ для приложений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...