我有两个相互依赖的课程。我以前解决过这个问题,但我一生都不记得如何解决这个问题。我的简化代码是这样的:
struct MenuOption{
string Text;
int Choice;
bool UseSubMenu;
Menu SubMenu;
};
class Menu{
public:
Menu(MenuOption optionlist[],int optioncount);
};
我有两个相互依赖的课程。我以前解决过这个问题,但我一生都不记得如何解决这个问题。我的简化代码是这样的:
struct MenuOption{
string Text;
int Choice;
bool UseSubMenu;
Menu SubMenu;
};
class Menu{
public:
Menu(MenuOption optionlist[],int optioncount);
};
IE:
// Forward declaration to assure A of B's existence.
class B;
class A { // uses B
B* b;
};
class B { // uses A
A* a;
};
使用前向声明
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;
};
您需要使用指针而不是对象。我相信在这种情况下SubMenu
需要Menu*
编辑
实际上,正如其他人提到的,前向声明也是需要的。但是使用前向声明,您可以只定义指针/引用,但不能创建对象。当您尝试创建一个对象时,编译器需要知道sizeof
该对象是什么,这是不可用的(即使您转发声明)。使用前向声明,您告诉编译器Menu
是类型class
,并且您正在存储指向Menu
类型对象的指针。想一想,一个实例进入另一个实例将是无限的recursion。
class Menu;
struct MenuOption{
string Text;
int Choice;
bool UseSubMenu;
Menu* SubMenu;
};
class Menu{
public:
Menu(MenuOption optionlist[],int optioncount);
};
基本上,您“前向声明”类菜单,然后使用指向菜单的指针作为子菜单。