2011-01-04 6 views
0

抽象的なインタフェースの静的配列を初期化したいと思います。私はちょうどデータを構築する静的関数への呼び出しが有効な初期化手段であるかどうか疑問に思っています。下のコードでポインターが指しているデータの寿命はどのように見えますか?静的関数の非静的データの長さ

typedef class FOO { 
public: 
    static const int** array_int; 
    static const int** array_int_init(); 

} FOO; 

const int** FOO::array_int_init() 
{ 
    const int A = 5; 
    const int B = 6; 
    const int C = 7; 

    const int* array_int[] = { &A, &B, &C }; 

    return &array_int[0]; 
} 
const int** FOO::array_int = array_int_init(); 

また、C++仕様でこのような動作の詳細を見つける最も良い方法は何ですか?私はN3225 = 10-0215を持っていますが、インデックスとコンテンツを見ても、私は答えを約束することなくたくさん読む必要があります。

+2

'typedefクラスFoo {...} FOO;'はC++では本当に必要ではありません。単純な 'class Foo {};'は絶対に十分です。 –

+1

@ Polybos:実際、C++ではこれは決して必要ではありませんでした。 – sbi

+0

@sbi明快さの欠如のため申し訳ありません:)私は言いたいと思いました:Cではそれは必要でしたが、C++ではそれはもはやありません。 –

答えて

2

変数はローカルであり、関数が終了すると存在しなくなります。あなたがそれらを必要とする場合は、これらの静的変数は限りプログラムとして続くとあなたがそれを注意してください(関数を呼び出す最初に初期化されます

const int** array_int_init() 
{ 
    static const int A = 5; 
    static const int B = 6; 
    static const int C = 7; 

    static const int* array_int[] = { &A, &B, &C }; 

    return &array_int[0]; 
} 

で関数内staticとして両方VARSや配列を宣言し、その後生き残るためにしかし、初期化が上記の場合と同じくらい簡単ではない場合、多少の処理が必要です。

+0

@Tal、 'array_int'は単なるポインタであり、' array_int_init() 'の内部で定義された静的を指すことができます。@ 6502マルチスレッドはここでは問題ではないと思います。 – Nim

+0

ええ、申し訳ありませんが、静的メンバーがこの関数を呼び出して初期化されたことに気付かなかった。 –

+0

静的関数データは呼び出し間に保持されますが、移動することはありませんか? –

1

コードを見ると、静的データメンバ 'array_int'を実際に初期化するメソッドの代わりに、同じ名前のローカル配列が作成され、その戻り値として返されるようです。これは実際に2つのバグを引き起こします:

  1. 'array_int'メンバは未初期化のままです。編集:私の間違いは、戻り値で静的メンバーを初期化することに気付かなかった。この点を無視してください。
  2. 'array_int_init()'の戻り値は、ローカル配列のアドレスであり、メソッドが返った時点では無効になります。実際には、配列の値は自身のローカルの他のローカル変数になります。そのアドレスは、関数が返っても有効ではありません。

しかし、あなたの一般的な質問に答えるには、静的なクラスメンバを初期化するために静的なクラス関数を呼び出すだけで十分です(何も返す必要はありません)。終了する。

編集:コメントに基づいて、私はここにいくつかの混乱があると思うので、より良い説明をしようとします。

元のコードには、FOO :: array_intという静的データメンバーがあります。そのデータメンバーはではなく、でコード内で初期化またはアクセスされています。

関数array_int_init()には、関数の戻り値としてアドレスが返されるローカル変数もあります。さて、静的変数と、その配列にデータを格納するために使用されるアドレスを持つすべてのint変数は、スタックにすべて割り当てられているため、関数が返っても無効になります。それがVC10で動作するように思われる理由は、関数が戻る直後、前のデータを上書きするスタックに他の情報が割り当てられる前に、返された配列にアクセスしているからです。しかし、それは「本当の」アプリケーションでは機能しません。

+0

)1. array_intはFOO :: array_int_init()によって初期化されます。 2.)静的データは、所有プロセスの存続期間中残ります。 – YeenFei

+0

これはVC10でこのコードを実行すると、まさに私が期待することですが、すべてがとてもうれしいです。これは当然、私にはむしろ愚かな質問をするようになった。初期設定を例外として、なぜあなたはそれを言っているのか分からない。 –

+0

私はこの回答がなぜマークダウンされたのか分かりません。両方の点が有効です(最初の論争で、それはひっくり返して初期化されます。つまり戻り値です)。 @PrettyFlower、それが動作すれば、それは純粋な運である - それを行う正しい方法は、その答えの@ 6502状態です。 – Nim

関連する問題