2017-02-27 5 views
0

静的メンバーはconstとして宣言できますが、宣言で初期化する必要があります。ループ内のコードで初期化される静的配列の次の場合を考えてみましょう。ループで初期化されるstatic constクラス値を作成する方法はありますか?

class A { 
private: 
    enum { SIZE = 360 }; 
    static double* vertices; 
public: 
    static void staticInit(); 
}; 

double* A::vertices = new double[SIZE]; 
void A::staticInit() { 
    double a = 0, b = 0; 
    for (int i = 0; i < SIZE; i++, a += .01, b += .02) 
    vertices[i] = sin(a) + c2 * sin(b); 
} 

上記のコードは機能します。しかし、頂点を定数にすることが意図されている場合、それをconst宣言するとstaticInit関数でコンパイルエラーが発生します。

古いC++では、ポインタconstを宣言してこの関数内で非constにキャストしますが、今日ではコンパイラは安全でないためこれを許可しません。もちろん、ポインタconstを宣言することはさらに危険ではありません。

清掃方法はありますか?

答えて

3

それを呼び出すことによってstatic値を初期化し、その後、std::arrayを返すmakeVertices関数を作成する:

class A { 
private: 
    static std::array<double, size> vertices; 
}; 

std::array<double, size> A::vertices = makeVertices(); 

makeVerticessize両方がA内で定義することができる。)

constexpr std::size_t size = 360; 

std::array<double, size> makeVertices() 
{ 
    std::array<double, size> vertices; 
    double a = 0, b = 0; 

    for (int i = 0; i < size; i++, a += .01, b += .02) 
     vertices[i] = sin(a) + c2 * sin(b); 

    return vertices; 
} 

をまた、enumの代わりにconstexprを使用して、コンパイル時のnumエリカル定数 - それは慣用的なC++ 11です。

+1

ありがとうございます、はいまだ "古い" C++の反射があります – Dov

2

なぜあなたはあなたが気にするすべてのものを作ることができなかったのか分かりません。ユースケースを簡素化するには:

const T * const p = Init(); 

T * Init() 
{ 
    T * result = new T[n]; 
    for (std::size_t i = 0; i != n; ++i) 
     InitOne(result[i]); 
    return result; 
} 

このスキームを静的なクラスメンバーに適用できるはずです。

関連する問題