2016-12-22 5 views
8

をもたらすキャッシュ -静的定数は、次の例で

[21] 21

[22] 21

[23] 21 -

#include <iostream> 

int someMethod(){ 
    static int a = 20; 
    static const int result = a + 1; 
    ++a; 
    std::cout << " [" << a << "] "; 
    return result; 
} 

int main(){ 
    std::cout << someMethod() << "\n"; 
    std::cout << someMethod() << "\n"; 
    std::cout << someMethod() << "\n"; 
} 

出力として付属します

同じ関数を呼び出した後にresultの値が変更されないようにする理由は何ですか?私は変数aの出力も印刷しましたが、確かにインクリメントされています。静的なので同じメソッドに対して複数のコピーが存在してはいけません。

IDEONEからCOMPILER OUTPUT

+1

理由は静的なconstですか? – EJP

答えて

3

を呼び出し回数に関係なくconst 1回だけ実行されruntime.Therefore中に1回だけ初期化されますここでは、読者を本当の原因から邪魔するだけです。このコードはまったく同じ動作をします。 (たびに実行される)逢引または初期化(変数が作成されている場合にのみ実行される):

int someMethod(){ 
    static int a = 20; 
    static int result = a + 1; 
    ++a; 
    std::cout << " [" << a << "] "; 
    return result; 
} 

本当の理由は、=符号は、2つの異なるC++の動作を表すことができることです。変数の宣言/定義の一部である場合の相違。通常のコンテキスト(ないブロック静的変数)で

、自動変数は、実行(又は少なくともコンパイラはすべてそれかのようを動作することを保証しなければならないと宣言されたブロックするたびに作成されるため、両者が同等ですその場合)。

ブロック静的変数の場合、初期化は1回だけ実行され、変数結果は21に初期化され、その値は決して変更されません。

これらの変異体は

int someMethod(){ 
    static int a = 20; 
    static int result; 
    result = a + 1; // assignation: result will see its value change with the value of a 
    ... 

int someMethod(){ 
    static int a = 20; 
    static const int result = a; 
    result = a + 1; // Error modification of a const declared variable 
+3

良い答えですが、最後のコードブロックの最後の2行には2つの小さなエラーがあります。 'static const int result'はconstであるため初期化されなければならず、次の行で 'result'を変更すると、未定義の動作ではなくコンパイラエラーに終わります。 – Tunichtgut

+0

@Tunichtgut気づいてくれてありがとう!投稿は編集されました... –

4

resultが静的​​であるので、それは次の行は、あなたがsomeMethod()

static const int result = a + 1; 
+0

@Georgeはい、私はinitialize.static変数が一度だけ初期化されたことを意味しました。右? –

+0

@George。理由を説明してください。 –

+2

@George Eh?ローカル静的関数の初期化は、制御が宣言の上を初めて流れるときにのみ行われます。だから、なぜイニシャライザは何度も何度も評価されるだろうか? – Praetorian

1

違うくらいだろう静的には、プログラムのデータセグメントに変数の値を割り当てるために、コンパイラを強制別に変数を再初期化しないように、コンパイラへのヒントです。

0

staticであるため、最初の実行時にはsomeMethod()に初期化されます。

そしてresultconstので、

static const int result = a + 1; 

で割り当てられた最初の値は、プログラムの次の実行のために修飾されていないままです。

の参照を使用して達成可能なことを期待していたとします。

static const int & result = a; 
       ^
// note the & ---| 

を次のように前の行を変更する場合は、aresultをリンクし、resultを変更して出力

[21] 21 
[22] 22 
[23] 23 

問題は、あなたが別の変数に変数を参照することができることであるaを変更します表現ではない。 resultaにリンクし、a+1にリンクすることはできません(動的値a+1ではなく)。その次の行

static const int & result = a + 1; 

コンパイルが、(someMethod()の最初の実行で)保存されている無名の変数に(私が間違っていないよ場合)リンクresult表現a + 1の結果、その出力は再びです

[21] 21 
[22] 21 
[23] 21 
+0

私は 'a + 1'バージョンが合法だと思いますが(もちろんあなたが言うように固定値を参照しています) –

+0

@MM - 申し訳ありませんが...' a'も 'static'です関数への後続の呼び出しでリファレンスがぶら下がりますか? – max66

+0

あなたはそうです、私は 'a'が何らかの理由で関数のパラメータであったバージョンを想像していました –

関連する問題