2017-01-31 6 views
4

なぜ私はこの記述することができます。ここで静的な理由は何ですか?

class VoiceManager 
{ 
public: 
    static const int mMaxNumOfVoices = 16; 
    Voice mVoices[mMaxNumOfVoices]; 

private: 
}; 

を私はこれを使用することはできません。

class VoiceManager 
{ 
public: 
    const int mMaxNumOfVoices = 16; 
    Voice mVoices[mMaxNumOfVoices]; 

private: 
}; 

をそれは言う:「非静的メンバ参照は、特定のオブジェクトを基準にする必要があります

どちらの場合も、mMaxNumOfVoicesconstであり、mVoicesの前にinitになります(コンパイラは宣言順に従います)。

ただし、staticが必要です。どうして?

+0

状況とエラーメッセージをしてください。 – LogicStuff

+0

おそらく、ランタイムまでに 'mMaxNumOfVoices'がどのようなものになるのだろうか? 'static'を使うと、この値を知ることができます。 –

+2

私は 'const'だけではコンパイル時定数にならないと思いますが、' static const'は – torkleyy

答えて

16

コンパイル時に配列の境界を知る必要があります。初期化はコードに記述されていますが、実行時にコンストラクタでオーバーライドすることができます。したがって、あなたの非staticメンバ変数はコンパイル時定数ではありません。

+0

"は、実行時にコンストラクタ" uhm、no! "によってオーバーライドできます。それはconstです。上書きすることはできません(少なくとも、そうしないでください)。 – markzzz

+8

@paizza - [はいできます](http://ideone.com/kcdFBe)非初期化メンバ変数は、たとえ初期化子がデフォルトで提供されていても、その値を常にコンストラクタに設定できます。 – StoryTeller

+1

または古い[コンストラクタ初期化構文](http://ideone.com/rsVBdY)を使用してください。 –

1

constキーワードは、定数ではなく読み取り専用であり、プログラムの特定の部分について変更されていない約束のようなものです。あなたがポインタへのポインタを持っているなら、あなたが見ていない間、プログラムの他の部分が値を変えるかもしれません。

しかし、static constは、残りのプログラムでは変更されないことが保証されています。オブジェクトの記憶域は、プログラムの開始時に割り当てられ、プログラムの終了時に割り当てが解除されます。オブジェクトのインスタンスは1つだけ存在します。名前空間のスコープ(グローバル名前空間を含む)で宣言されたすべてのオブジェクトは、この保存期間を持ちます。

+0

このように 'const'を使うことで、変数はその生涯にわたって変更されないままになります。 pointer-to-constに関する大文字小文字はこのコードには当てはまりません。また、静的constは、odrが使用されていない場合はストレージを全く持たないかもしれません。ストレージを持つ静的なものであれば、最初の使用まで初期化を遅らせることができ、定数式ではない可能性があります。このコードは(クラスではなく)あなたの説明が正しくないことを示しています: 'static const int x = foo(); int y [x]; ' - エラー –

関連する問題