我有两个相互依赖的类。我已经解决了这个问题,但我不能为我的生活记住如何解决这个问题。我的简化代码是这样的:如何解决依赖类?
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);
};
即:
// Forward declaration to assure A of B's existence.
class B;
class A { // uses B
B* b;
};
class B { // uses A
A* a;
};
您需要使用指针而不是对象。我beleive在这种情况下SubMenu
必须还需要Menu*
编辑
其实是别人提到的向前声明。但是前向声明你可以定义指针/引用,但是你不能创建一个对象。当你尝试创建一个对象时,编译器需要知道该对象的sizeof
是什么,这是不可用的(即使你转发声明)。使用前向声明,您告诉编译器Menu
的类型为class
,并且正在查找指向Menu
类型对象的指针。考虑一下,有一个实例到另一个实例将无限recusrion。
我不明白为什么我需要在这种情况下使用指针。谨慎解释?不正确的宣布是否足够? (除了我的类实际上没有“学习”指针的事实) – Earlz 2010-09-27 09:08:25
定义结构时,编译器需要知道结构的大小。当一个前向声明完成时,它告诉编译器一个类存在但不是它的大小。这意味着当编译器试图确定MenuOption的大小时,它不能推断出它,因为它不知道菜单的大小,菜单的大小只能在* MenuOption之后确定*。 但是,如果它是指向类的指针,编译器不需要知道类的大小,因为它只是一个指针,指针的大小是固定的(取决于CPU体系结构)。 – 2010-09-27 09:21:13
class Menu;
struct MenuOption{
string Text;
int Choice;
bool UseSubMenu;
Menu* SubMenu;
};
class Menu{
public:
Menu(MenuOption optionlist[],int optioncount);
};
基本上,你“向前申报”类菜单,然后使用一个指向菜单的子菜单。
使用前置声明
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;
};
啊。这就说得通了。我完全忘记了会产生的递归无限大小结构。 – Earlz 2010-09-27 09:09:51