2017-02-09 15 views
1

だから、私はクラスの静的フィールド(特に一定のもの)を試して、この....に自分自身を持ってきました:この静的クラスフィールドは作成前に使用されていますか? 、どうやら</p> <p><a href="https://i.stack.imgur.com/L0jGo.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/L0jGo.png" alt="Output"></a></p> <p>:

#include <iostream> 
#include <conio.h> 

class Test { 
public: 
    Test() { std::cout << "Constructing (Default CTOR)\n"; } 
    Test(int f) { std::cout << "Constructing (Int arg CTOR)\n"; } 

    void method() const { std::cout << "Already constructed and being used\n"; } 
}; 

class Stack { 
public: 
    // static const Test what{ 5 }; // - "element of type "const Test" can not have an initializer inside of a class" 
    // const Test ok{ 5 }; // now it can (?) 

    static const Test what; 

    Stack() { 
     what.method(); 
    } 

    // Stack() : what{5} {} // can't do that because "what" will be dependent on object creation (which is not how static class fields roll) 
}; 

Stack obj; 

const Test Stack::what{}; 

int main() 
{ 
    _getch(); 
    return 0; 
} 

出力実際に作成される前に、static const Test whatStackが使用されています(?)。

はその後、私は別のテスト実行:このコードで

#include <iostream> 
#include <conio.h> 

class Test { 
public: 
    int data; 

    Test() { std::cout << "CONSTRUCTING (Default CTOR)\n"; } // notice, value-initialization of 'data' has been removed 
    Test(int f) : data{ f } { std::cout << "CONSTRUCTING (Int arg CTOR)\n"; } 

    void method() const { std::cout << "ALREADY CONSTRUCTED AND BEING USED :)\n" << data << std::endl; } 
}; 

class Stack { 
public: 
    static const Test what; 

    Stack() { 
     what.method(); 
    } 
}; 

Stack obj; 

const Test Stack::what{ 5 }; 

int main() 
{ 
    obj.what.method(); 

    _getch(); 
    return 0; 
} 

を私はエラーのいくつかの並べ替えを見て期待していたが、出力は次のように見てしまった:

Output 2

Iここで何が起こっているかについていくつかの仮定をしていますが、正しいかどうかはわかりません。もしそうなら、私を修正してください。ここで

は私の仮定です:

基本的には、静的変数は、プログラムの非常に開始時に作成(および値に初期化されている)と、プログラムの最後にdestoyedされている(あなたが実際にあなたの.exeファイルを閉じると、 )。 私の例では、私は静的定数変数whatをクラスStackに入れています。プログラムの初期化時に値が初期化されていると思います。そのため、そのdataフィールドが0に設定され、そのメソッドを使用することができます。しかし、コンソールにConstructing (Default CTOR)を出力したので、正しいとは思わない。だから私はちょっとそこにこだわっています...

私の最初の例のコメント行が違法である理由もわかりません。静的/定数クラスフィールドのどのルールが正確に壊れていますか?

私の例で何が起こっているのか分かっていれば、それを説明してください。

ご協力いただきありがとうございます。

+0

デフォルトのコンストラクタが実際にオブジェクト内の何かを変更しないという事実には疑問があります。 2番目のデフォルトのコンストラクタを ':data {1}'に変更するとどうなりますか? – Barmar

+0

@Barmar、nothing。出力は変わらず、エラーもありません。 –

+0

'#include 'なので、コードをコンパイルできません。あなたが標準のC++に固執していたなら、私はあなたを助けることができたでしょう。 – nwp

答えて

1

名前空間スコープ(つまり、関数内ではない)での静的変数は、ソースファイル内の定義の順番で構築されます。この順序付けは、同じソースファイル内の変数間でのみ適用され、異なるソースファイル間では適用されません。

したがって、objは、常にwhatより前に構築されます。コンストラクタを持っているが、コンストラクタが呼び出される前に、オブジェクトで行うことができる制限があります。メンバ関数を呼び出すことはその1つではありません(C++ 14 [basic.life] /5.2)。だから、のコンストラクタのwhat.method()コールは未定義の動作を引き起こします。

+0

ああ、私は参照してください。有益な答えをありがとう!だから私の2番目のexmapleの出力でゼロは、すべての後にエラーがあったはずです:) –

関連する問題

 関連する問題