Как разрешить зависимые классы? - PullRequest
1 голос
/ 27 сентября 2010

У меня есть два класса, которые зависят друг от друга.Я решил эту проблему раньше, но не могу на всю жизнь вспомнить, как это исправить.Мой упрощенный код такой:

struct MenuOption{
  string Text;
  int Choice;
  bool UseSubMenu;
  Menu SubMenu;
};

class Menu{
public:
  Menu(MenuOption optionlist[],int optioncount);
};

Ответы [ 4 ]

3 голосов
/ 27 сентября 2010
  • Использовать предварительные объявления

Т.е.:

// Forward declaration to assure A of B's existence.
class B;

class A { // uses B
  B* b;
};

class B { // uses A
  A* a;
};
  • Использовать указатели, а не экземпляры объектов: поскольку компилятор должен знать, сколько места выделеночленам класса.Поэтому наличие экземпляра объекта работать не будет, потому что компилятор не знает его размера, не увидев полное объявление своего класса.Однако все указатели имеют одинаковый размер, который известен компилятору, не глядя на что-либо дополнительное.
1 голос
/ 28 сентября 2010

Использовать предварительные объявления

struct MenuOption;

class Menu{
public:
  Menu(MenuOption optionlist[],int optioncount);
};

struct MenuOption {
  string Text;
  int Choice;
  bool UseSubMenu;
  Menu SubMenu;
};

Вам не нужно указывать какой-либо элемент данных.В приведенном выше фрагменте кода нет «рекурсивного бесконечного размера».

Независимо от этого, все еще выглядит хорошей идеей сделать этот SubMenu указателем.Потому что, кажется, нет необходимости иметь подменю, не так ли?Поэтому вы должны использовать указатель, так как в противном случае этот элемент будет всегда меню и должен быть инициализированУказатель можно оставить неинициализированным или как нулевой указатель.Вы также можете использовать boost::optional<> вместо

struct MenuOption {
  string Text;
  int Choice;
  boost::optional<Menu> SubMenu;
};
0 голосов
/ 27 сентября 2010
class Menu;
struct MenuOption{
  string Text;
  int Choice;
  bool UseSubMenu;
  Menu* SubMenu;
};

class Menu{
public:
  Menu(MenuOption optionlist[],int optioncount);
};

По сути, вы «объявляете вперед» класс Menu, а затем используете указатель на Menu в качестве подменю.

0 голосов
/ 27 сентября 2010

Вам нужно использовать указатели вместо объектов. Я считаю, что в этом случае SubMenu должно быть Menu*

EDIT

На самом деле, как и другие упомянутые предварительные декларации, также необходимо. Но с помощью предварительных объявлений вы можете просто определить указатель / ссылку, но вы не можете создать объект. Когда вы пытаетесь создать объект, компилятор должен знать, что такое sizeof объекта, который недоступен (даже если вы перешлите объявление). При предварительном объявлении вы сообщаете компилятору, что Menu имеет тип class, и вы указали указатель на объект типа Menu. Подумайте об этом, иметь экземпляр один в другой будет бесконечное возвращение.

...