1

我有两个相互依赖的课程。我以前解决过这个问题,但我一生都不记得如何解决这个问题。我的简化代码是这样的:

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

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

4 回答 4

3
  • 使用前向声明

IE:

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

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

class B { // uses A
  A* a;
};
  • 使用指针而不是对象实例:因为编译器需要知道为类的成员分配多少空间。因此,拥有一个对象实例是行不通的,因为编译器在没有看到其类的完整声明的情况下不知道它的大小。然而,指针都具有编译器已知的相同大小,无需查看任何额外内容。
于 2010-09-27T09:05:39.913 回答
1

使用前向声明

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;
};
于 2010-09-27T20:06:35.560 回答
0

您需要使用指针而不是对象。我相信在这种情况下SubMenu需要Menu*

编辑

实际上,正如其他人提到的,前向声明也是需要的。但是使用前向声明,您可以只定义指针/引用,但不能创建对象。当您尝试创建一个对象时,编译器需要知道sizeof该对象是什么,这是不可用的(即使您转发声明)。使用前向声明,您告诉编译器Menu是类型class,并且您正在存储指向Menu类型对象的指针。想一想,一个实例进入另一个实例将是无限的recursion。

于 2010-09-27T09:05:10.163 回答
0
class Menu;
struct MenuOption{
  string Text;
  int Choice;
  bool UseSubMenu;
  Menu* SubMenu;
};

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

基本上,您“前向声明”类菜单,然后使用指向菜单的指针作为子菜单。

于 2010-09-27T09:05:48.033 回答