2016-07-19 8 views
5

コンパイル/リンク処理については多くの参考文献がありますが、より具体的な問題に興味があります。クラスのコンパイルです。クラスのコンパイルはどのように機能しますか?

問題は、一般に使用する前に物事を知る必要があるために発生します。たとえば、以前に宣言されていない関数を呼び出すことはできません。

クラスでは、同じように行われません。メンバーは、表示される前に使用することができます。コンパイラは何をしていますか?標準はコンパイルの前の段階について何かを教えていますか?

より具体的には、以下の例は、以下に定義されたメンバーをどのように使用できるかを示しています。

#include <iostream> 

class EvenOdd { 
public: 
    EvenOdd(): value(0) {} 

    void assignEven(unsigned v) { 
     if (v>0 && v%2==1) { 
     std::cout << "Wrong call... is odd" << std::endl; 
     assignOdd(v); 
     } 
     else { 
     std::cout << "Right..." << v << " is Even" << std::endl; 
     value= v; 
     } 
    } 
    void assignOdd(unsigned v) { 
     if (v>0 && v%2==0) { 
     std::cout << "Wrong call... is even" << std::endl; 
     assignEven(v); 
     } 
     else { 
     std::cout << "Right..." << v << " is Odd" << std::endl; 
     value= v; 
     } 
    } 
private: 
    unsigned value; 
}; 

int main() 
{ 
    EvenOdd a; 
    std::cout << "Do it right..." << std::endl; 
    a.assignEven(2); 
    std::cout << "doing it wrong..." << std::endl; 
    a.assignEven(3); 
} 

呼び出しポイントの後に定義される可能性のあるインライン関数についてさらに質問を加えることができ、コンパイラは問題なく解決できます。私は答えが関連していると思います。

更新:私はコンパイル/リンケージがいくつかのステップを持っていることを知っています。一方、コンパイラが以下の関数を呼び出すことを受け入れるならば、コンパイラはある意味でコードを解析します。問題は以前にどのような前段階が行われたのですか?さらに、標準のどの部分で、定義されたメンバーを使用するのに関連する何かが見つかりましたか?

コンパイラがどのように動作するかを知ることは、コンパイルするために実際に対応していると思われる機能についての詳細を知る必要があるためです(少なくともヘッダー)。

コードの並べ替えのように機能しますが、両方の関数メンバーが互いに呼び出すため、上記の例とは一致しません。データメンバでさえ、コンパイルする必要があります。これは、データメンバーを並べ替えるようなものであり、関数のヘッダーは、コンパイラーによって考慮されるコードである可能性があります。

+0

コンパイルには複数のステップがあります。 – axiac

+1

@axiacええ、しかし、OPはそれについて知っているようです。私は彼らが本当になぜ関数の前の宣言が必要だが、クラスのメンバーのために必要なのかと尋ねると思う。それは矛盾しているようです。 – luk32

+0

ありがとう@ luk32、それは質問です! – EFenix

答えて

7

標準は言う

クラスは、クラス指定の閉鎖}で完全に定義されたオブジェクトのタイプ(3.9)(または完全なタイプ)であると考えられます。クラスメンバ仕様の中では、クラスは、関数本体、デフォルト引数、例外仕様、およびデフォルトのメンバ初期化子(ネストされたクラスのものを含む)内で完全であるとみなされます。さもなければそれはそれ自身のクラスメンバー仕様の中で不完全とみなされます。

これは、特に、メンバ関数本体が、その下に宣言されたクラスメンバを参照する可能性があることを意味します。標準では実装がこれをどのように達成するかは気にしません。 1つの可能な方法は、クラスの閉じ括弧が見えるまで、上で指定されたメンバ関数本体および他の要素の意味解析を延期することである。

0

クラス内の関数は、データメンバが既にクラス内で宣言されているため、(関数が定数でない限り)データメンバにアクセスして変更することはできません。なぜ機能がクラスで宣言を必要としないのあなたの応答で。

+0

残念ながら5分遅れ...(y) – hsqureshi

関連する問題