3

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

これが私の問題です、

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

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

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

上記のコードは問題なく動作します。しかし、foo呼び出しbarと私はbarの定義を前に置いfooたり、前方宣言したりしませんbarでした。呼び出しをどのように機能させることができbarますfooか?コンパイラはどのようにして見つけることができますbarか?

4

4 に答える 4

5

言語は、メンバー関数宣言のスコープがクラス全体であると (大まかに) 言っているので、これで問題ありません。

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

barそのため、クラスの最後にあるへの呼び出しのみを確認し、その時点でその宣言を確認しており、すべて問題ありません。

于 2012-03-03T04:19:45.050 に答える
3

クラスの定義内で定義されたメンバー関数の本体は特殊なケースです。名前検索の目的では、クラス定義の終了直後にメンバー関数が定義されたかのようになります。

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

于 2012-03-03T04:16:47.130 に答える
3

実は、そう呼ばれているForward reference

前方参照という用語は、前方宣言の同義語として使用されることがあります。ただし、宣言の前にエンティティの実際の使用を参照することがよくあります。つまり、上記のコードの最初の 2 番目の参照は前方参照です。したがって、Pascal では前方宣言が必須であるため、前方参照は禁止されていると言えます。

前方参照を許可すると、コンパイラの複雑さとメモリ要件が大幅に増加する可能性があり、通常、コンパイラを 1 回のパスで実装できなくなります。

于 2012-03-03T04:18:57.470 に答える
1

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

于 2012-03-03T04:19:55.953 に答える