2011-01-27 4 views
4

時にアレイメンバー、メンバーを初期化し、すべてが正常に動作します:C++:静的は、私は今、私はグローバルスコープでこれを行うことができます

const char* Foo::bars[3] = {"a", "b", "c"}; 

しかし、これは、はるかに明確かつ自己であるので、私はこれをしたいです文書化(特にEnumをインデックスとして使用する場合):

const char* Foo::bars[3]; 
bars[0] = "a"; 
bars[1] = "b"; 
bars[2] = "c"; 

これはどうしてですか?

私は関数(例えば、クラスのコンストラクタ)内でこれを行うことができますが、コンストラクタがプログラムの開始時に呼び出されず、静的配列を使用したい場合はどうすればよいですか?それは問題につながります。

+2

なぜコンストラクタを呼び出さないのですか? – Simone

+0

OPは、Foo :: barsを静的メンバーにし、その要素を静的に(メインが実行される前に)初期化するようにします。 –

+1

@Emileはい、OPの最初のコード行は、 'bars'が静的宣言されている場合とまったく同じです。コンストラクターが呼び出されるので、私は全体の議論のポイントを見逃します。 – Simone

答えて

1

C++には、static Javaブロックに相当するものはありません。

あなたが本当に自動的に配列を初期化したい場合は、あなたが仕事をする単純なクラスを作成することができます。

// in .cpp 
class FooInitializer { 
public: 
    FooInitializer() { 
     Foo:bars[0] = "a"; 
     Foo:bars[1] = "b"; 
     Foo:bars[2] = "c"; 
    } 
}; 

static FooInitializer fooInitializer; 
7

これはいかがですか?

const char* Foo::bars[3] = { 
/* Index Value */ 
/* 0 */  "a", 
/* 1 */  "b", 
/* 2 */  "c" 
}; 

この「技法」を使用して、構造体の配列の初期化を自己文書化スプレッドシートのようにすることがよくあります。

+0

+1、良いアイデア。 :) –

+0

"コンストラクタが呼び出されていない"場合、OPと同じコードなので、動作しません。とにかく、なぜ呼び出されてはならないのか聞かないでください... – Simone

+0

@Simone:OPは、Foo :: barsを静的メンバーにしたいと思って、プログラムが実行される前にそれらを初期化します。しかしOPは初期化構文が気に入らない。はい、コードは同じですが、配列のインデックスを各配列要素に表示するためのインラインコメントを追加しました。原油、はい、しかし効果的な、IMHO。 –

0

あなたはアクセサ関数を使用することができます。

const char* GetArray() 
{ 
    static char* result[3]; 
    static isInitialized = false; 
    if (!isInitialized) 
    { 
     result[0] = "a"; 
     result[1] = "b"; 
     result[3] = "c"; 
     initialized=true; 
    } 
    return result; 
} 
+0

"a"、 "b"、 "c"リテラルにローカルスコープがありますか?私はこれがぶら下がり指針をもたらすかもしれないと思う。 –

+0

私は少しの研究をしました...実際に文字列リテラルはグローバルスコープを持っています。 –

+0

このソリューションはスレッドセーフではないことに注意してください。なぜなら、この関数はリエントラントではないからです。 –

0

ここでもう一つの解決策ですSingletonパターンを使用します。配列はシングルトンのコンストラクタで一度初期化されることに注意してください。また、これはスレッドセーフではありません。また、シングルトンの邪悪に気をつけてください(このサイトで、この問題に関するいくつかの興味深い議論を見つけるために "シングルトン"を検索してください)。

#include <iostream> 

class StringTable 
{ 
public: 
    enum StringId 
    { 
     hello, 
     bye, 
     goodDay, 
     stringCount 
    }; 

    static const char* lookup(StringId id) {return instance().table_[id];} 

private: 
    StringTable() 
    { 
     table_[hello] = "Hello World!\n"; 
     table_[bye] = "Goobye, cruel world!\n"; 
     table_[goodDay] = "I said good day!\n"; 
    } 

    static StringTable& instance() 
    { 
     static StringTable theInstance; 
     return theInstance; 
    } 

    const char* table_[stringCount]; 
}; 


int main() 
{ 
    std::cout << StringTable::lookup(StringTable::hello) 
       << StringTable::lookup(StringTable::bye) 
       << StringTable::lookup(StringTable::goodDay); 
} 
0

あなたはおそらく、あなたがそれを宣言した方法は、あなたが使用したいが、あなたが実際に、一度にメンバー1を設定する際に何を望むかを行うことができ、

const char* const Foo::bars[3] = 
{ 
    "a", 
    "b", 
    "c" 
}; 

バーに余分のconstをしたいですそれを行うための "init"関数。

constが必要な場合は、「init」メソッドであっても一度に1行ずつ割り当てるのが不正となり、単純にコードレイアウトを使用してコードを作成してくださいあなたがしていることをより明確にする。

関連する問題