2012-03-03 11 views
3

C/C++では、呼び出し元関数が呼び出し元に表示されている場合のみ、呼び出し元関数が呼び出し先関数を呼び出します。それ以外の場合は前方宣言を使用します。ここで関数はC++で使用する前に定義します。

は、上記のコードはうまく動作します

class A 
{ 
    public: 
     void foo() 
     { 
      bar(); 
     } 

     void bar() 
     { 
      //... 
     } 
}; 

int main() 
{ 
    A a; 
    a.foo(); 
} 

、私の問題です。しかし、foobarと呼ばれ、fooの前にbarの定義を入れなかったか、またはbarを先に宣言したのですが、foobarへの呼び出しはどうすればできますか?コンパイラはどのようにしてbarを見つけることができますか?

答えて

5

言語は、メンバ関数宣言の範囲は全クラス(緩く)であるので、これは微細であることを述べています。

実際には、コンパイラは、インライン関数の本体を解析する前に、クラス定義の終わり(実際には最も外側のクラス定義の終わり)まで待機します。

したがって、クラスの終わりにbarの呼び出しを見るだけで、宣言が見え、すべてがうまくいきます。

+0

関数の定義をクラスの本体から移動すると、クラス本体の関数宣言はforward-declとして機能します。 – Alcott

+0

はい。そしてそれらを両方向に動かすと、それらを任意の順序で定義することができます。 –

3

クラスの定義の中で定義されているメンバ関数の本体は特殊なケースです。名前ルックアップの目的では、メンバ関数がクラス定義の終わりの直後に定義されているかのようです。

これは、メンバ関数が定義されているクラス定義のどこに関係なく、メンバ関数がメンバであるクラスの他のメンバにそのメンバ関数の定義を参照させる理由です。

3

実際、それは時々前方宣言の同義語として使用される用語前方参照Forward reference

と呼ばれています。しかしながら、より多くの場合、宣言の前に実体の実際の使用を参照することが多い。つまり、上のコードの最初の2番目の参照は前方参照です。したがって、パスカルではフォワード宣言が必須であるため、前方参照は禁止されています。

前方参照を許可すると、コンパイラの複雑さとメモリ要件が大幅に増加し、コンパイラが1回のパスで実装されることが一般的に防止されます。

+0

あなたの答えによると、 'forward-reference'はC++では廃止予定ですか? – Alcott

+0

**前方参照**は、 'C++ 'の新機能で、' C'と比較しています。 – kev

1

(グローバルスコープではなく)クラス内の定義について話しているときは、別のことです。これはコンパイラが最初に定義のためにクラスを渡すことによって達成されると信じています。そしてすべてのメソッドの実際の実装を見てください。要約すると、この場合の前方宣言/参照のあらゆる種類について心配する必要はありません。

+1

定義する前にクラスメンバーである型を使用しようとすると、問題が発生します。 –

関連する問題