C++ 言語では、コンパイラはまだ定義されていない名前を先読みしません。つまり、より適切に言えば、先読みする場合とそうでない場合があります。
たとえば、次のように言うことができます
struct Foo
{
Foo(int x) : m_x(x) { }
int m_x;
};
m_x
何を定義する前に使用してもコンパイラは文句を言いませんm_x
が、モジュールレベルではこの先読みは存在しません:
struct Foo
{
Bar *p; // Error, Compiler doesn't know what Bar is
};
// Too late, the compiler is not going to read down here while
// analyzing Foo.
struct Bar
{
int x;
};
何かを定義する前に使用する必要がある場合、どのように解決しますか? 特別な「前方宣言」を使用することにより、その名前の何かがあることのみを述べ、後でそれが具体的に何であるかを定義します...たとえば
struct Foo; // There will be a struct Foo defined somewhere
struct Bar
{
Foo *p; // Fine, even if the compiler doesn't really know Foo
};
struct Foo
{
Bar *q; // Fine and no forward needed... Bar is known at this point
};
多かれ少なかれルールは次のとおりです。単一のクラスでは、すべてのメソッドは他のすべてのメソッドとすべてのメンバーをクラスで後で定義されている場合でも見ることができますが、代わりにモジュールレベルでは、すべての名前を使用する前に知っておく必要があります。
より複雑なパターンが必要な場合もあります。
struct Foo;
struct Bar
{
void doit(Bar x);
};
struct Foo
{
void doit_too(Foo x);
};
void Foo::doit(Bar x) { ... }
void Bar::doit_too(Foo x) { ... }
最後のケースでは、両方のクラスの宣言の後に両方のメソッドの実装を配置する必要があります。これは、それFoo
がクラスであることを知っているだけでは、コピー操作をコンパイルするのに十分ではないためです (メソッドのパラメーターは値によって渡されていることに注意してください)。 、ポインターまたは参照によるものではありません)。