Question

I have two classes which depend on each other. I've solved this problem before but I can not for the life of me remember how to fix this. My simplified code is this:

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

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

Solution

  • Use forward declarations

I.e.:

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

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

class B { // uses A
  A* a;
};
  • Use pointers and not object instances: because the compiler needs to know how much space to allocate to the members of a class. Having an object instance there is therefore not going to work because the compiler doesn't know its size without seeing the full declaration of its class. Pointers, however, all have the same size which is known to the compiler without looking at anything extra.

OTHER TIPS

Use forward declarations

struct MenuOption;

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

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

You don't need to make any data member a pointer. There is no "recursive infinite size" in the above code snippet.

Independent of this, it still looks like a good idea to make that SubMenu a pointer. Because it does not seem to be required to have a submenu, is it? So you should use a pointer since otherwise that member will always be a menu and needs to be initialized. A pointer can be left uninitialized or as a null pointer. You might also want to use boost::optional<> instead

struct MenuOption {
  string Text;
  int Choice;
  boost::optional<Menu> SubMenu;
};
class Menu;
struct MenuOption{
  string Text;
  int Choice;
  bool UseSubMenu;
  Menu* SubMenu;
};

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

Basically, you 'forward declare' the class Menu and then use a pointer to Menu as the SubMenu.

You need to use the pointers instead of objects. I beleive in this case SubMenu needs to be Menu*

EDIT

Actually as others mentioned forward declaration is also needed. But with forward declarations you can just define pointer/reference but you can not create a object. When you try to create an object the compiler needs to know what is the sizeof of the object, which is not available (even if you forward declare). With forward declaration you are telling the compiler that Menu is of type class and you are stroring a pointer to Menu type object. Think about it, having an instance one into another will be infinite recusrion.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top