互いに依存する2つのクラスがあります。私は以前にこの問題を解決しましたが、これを修正する方法を覚えていません。私の簡略化されたコードは次のとおりです。
struct MenuOption{
string Text;
int Choice;
bool UseSubMenu;
Menu SubMenu;
};
class Menu{
public:
Menu(MenuOption optionlist[],int optioncount);
};
互いに依存する2つのクラスがあります。私は以前にこの問題を解決しましたが、これを修正する方法を覚えていません。私の簡略化されたコードは次のとおりです。
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;
};
前方宣言を使用する
struct MenuOption;
class Menu{
public:
Menu(MenuOption optionlist[],int optioncount);
};
struct MenuOption {
string Text;
int Choice;
bool UseSubMenu;
Menu SubMenu;
};
データ メンバーをポインターにする必要はありません。上記のコード スニペットには「再帰的な無限サイズ」はありません。
SubMenu
これとは別に、それをポインターにすることはまだ良い考えのようです。サブメニューは必須ではなさそうですよね?そうしないと、そのメンバーは常にメニューになり、初期化する必要があるため、ポインターを使用する必要があります。ポインターは、初期化されていないままにするか、NULL ポインターとして残すことができます。boost::optional<>
代わりに使用することもできます
struct MenuOption {
string Text;
int Choice;
boost::optional<Menu> SubMenu;
};
オブジェクトの代わりにポインターを使用する必要があります。この場合、私はそうSubMenu
する必要があると信じていますMenu*
編集
実際、他の人が述べたように、前方宣言も必要です。ただし、前方宣言では、ポインター/参照を定義することはできますが、オブジェクトを作成することはできません。オブジェクトを作成しようとするとき、コンパイラはオブジェクトの内容を知る必要がsizeof
ありますが、これは利用できません (前方宣言を行ったとしても)。前方宣言でMenu
は、型であることをコンパイラに伝え、型オブジェクトclass
へのポインタをストレートしています。Menu
考えてみてください。インスタンスを別のインスタンスにすることは、無限の再利用になります。
class Menu;
struct MenuOption{
string Text;
int Choice;
bool UseSubMenu;
Menu* SubMenu;
};
class Menu{
public:
Menu(MenuOption optionlist[],int optioncount);
};
基本的には、Menu クラスを「前方宣言」してから、Menu へのポインタを SubMenu として使用します。