2017-02-27 37 views
0

靜態成員可能被聲明爲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

創建makeVertices函數返回一個std::array,然後通過調用它初始化static值:

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; 
} 

(兩者makeVerticessize可以內部A被定義)

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

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

還要注意使用constexpr而不是enum來表示編譯時數字erical常量 - 這是慣用的C++ 11。

+1

謝謝,是的,仍然有「舊」C++反射 – Dov

2

我不明白你爲什麼不能讓你關心的所有東西都變成const。爲了簡化用例:

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; 
} 

您應該能夠將此方案應用於您的靜態類成員。

相關問題