2010-09-27 129 views
1

我有两个相互依赖的类。我已经解决了这个问题,但我不能为我的生活记住如何解决这个问题。我的简化代码是这样的:如何解决依赖类?

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

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

回答

3
  • 使用前置声明

即:

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

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

class B { // uses A 
    A* a; 
}; 
  • 使用指针,而不是对象实例:因为编译器需要知道多少空间分配给一类的成员。有一个对象实例因此不会工作,因为编译器不知道它的大小而没有看到它的类的完整声明。然而,指针都具有编译器已知的相同大小,而不需要额外查看任何内容。
+0

啊。这就说得通了。我完全忘记了会产生的递归无限大小结构。 – Earlz 2010-09-27 09:09:51

0

您需要使用指针而不是对象。我beleive在这种情况下SubMenu必须还需要Menu*

编辑

其实是别人提到的向前声明。但是前向声明你可以定义指针/引用,但是你不能创建一个对象。当你尝试创建一个对象时,编译器需要知道该对象的sizeof是什么,这是不可用的(即使你转发声明)。使用前向声明,您告诉编译器Menu的类型为class,并且正在查找指向Menu类型对象的指针。考虑一下,有一个实例到另一个实例将无限recusrion。

+0

我不明白为什么我需要在这种情况下使用指针。谨慎解释?不正确的宣布是否足够? (除了我的类实际上没有“学习”指针的事实) – Earlz 2010-09-27 09:08:25

+0

定义结构时,编译器需要知道结构的大小。当一个前向声明完成时,它告诉编译器一个类存在但不是它的大小。这意味着当编译器试图确定MenuOption的大小时,它不能推断出它,因为它不知道菜单的大小,菜单的大小只能在* MenuOption之后确定*。 但是,如果它是指向类的指针,编译器不需要知道类的大小,因为它只是一个指针,指针的大小是固定的(取决于CPU体系结构)。 – 2010-09-27 09:21:13

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

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

基本上,你“向前申报”类菜单,然后使用一个指向菜单的子菜单。

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; 
};