web-dev-qa-db-ja.com

互いにデータとして使用する2つのクラスをC ++で作成する方法は?

2つのクラスを作成しようとしています。各クラスには、他のクラスタイプのオブジェクトが含まれています。これどうやってするの?これができない場合、各クラスに他のクラスタイプへのpointerを含めるなどの回避策がありますか?ありがとう!

私が持っているものは次のとおりです。

ファイル:bar.h

#ifndef BAR_H
#define BAR_H
#include "foo.h"
class bar {
public:
  foo getFoo();
protected:
  foo f;
};
#endif

ファイル:foo.h

#ifndef FOO_H
#define FOO_H
#include "bar.h"
class foo {
public:
  bar getBar();
protected:
  bar b;
};
#endif

ファイル:main.cpp

#include "foo.h"
#include "bar.h"

int
main (int argc, char **argv)
{
  foo myFoo;
  bar myBar;
}

$ g ++ main.cpp

In file included from foo.h:3,
                 from main.cpp:1:
bar.h:6: error: ‘foo’ does not name a type
bar.h:8: error: ‘foo’ does not name a type
39
Steve Johnson

2つのクラスに他のタイプのオブジェクトを直接含めることはできません。そうしないと、オブジェクトに無限のスペースが必要になります(fooにはbarを持つfooを持つbarなどがあるため)

ただし、2つのクラスに相互のポインターを格納させることで、実際にこれを行うことができます。これを行うには、2つのクラスが互いの存在を認識できるように、前方宣言を使用する必要があります。

#ifndef BAR_H
#define BAR_H

class foo; // Say foo exists without defining it.

class bar {
public:
  foo* getFoo();
protected:
  foo* f;
};
#endif 

そして

#ifndef FOO_H
#define FOO_H

class bar; // Say bar exists without defining it.

class foo {
public:
  bar* getBar();
protected:
  bar* f;
};
#endif 

2つのヘッダーが互いに含まれていないことに注意してください。代わりに、前方宣言を介して他のクラスの存在を知っているだけです。次に、これら2つのクラスの.cppファイルで、#includeクラスに関する完全な情報を取得するもう1つのヘッダー。これらの前方宣言により、「foo needs bar needs foo needs bar。」の参照サイクルを破ることができます。

93
templatetypedef

それは意味がありません。 AにBが含まれ、BにAが含まれる場合、サイズは無限になります。 2つの箱を入れて、両方を入れようとすることを想像してください。機能しませんよね?

ただし、ポインターは機能します。

#ifndef FOO_H
#define FOO_H

// Forward declaration so the compiler knows what bar is
class bar;

class foo {
public:
  bar *getBar();
protected:
  bar *b;
};
#endif
4
EboMike