2015-01-16 72 views
5

背景:我堅持arm-arago-linux-gnueabi-g++ (GCC) 4.3.3。儘管需要C++ 11或更高版本的答案也值得讚賞,但請明確表達任何語言要求比C++ 03晚。如何計算初始化一個常量數組(const const look-up-tables)?

對象的構造函數將值填充到算法要使用的表中。

由於這些表不改變,不應該改變,我希望他們是const,我該怎麼做?

難度#1,這些值是計算生成的,我不想在源文件中將它們硬編碼。

難點#2,計算有時取決於僅在運行時可用的輸入。

難度#3,我不知道爲什麼,但我不希望數組是靜態的,即使所有對象的值可能相同(值不取決於運行時輸入的情況)。

難點#4,它是一個數組,因此C++ 03中的初始化程序列表將不起作用。

EDIT1:這篇文章後 幾個星期,我發現兩者的std ::陣列和std ::向量是很好的替代C風格的數組時的std ::陣列不可用。

+4

裹與確保它只有一次初始化,並且僅提供了常量吸氣劑一類的數組。 – BartoszKP

+4

將數據標記爲「常量」並不真正爲您帶來任何價值。你可能讓它們在內存中是可變的,只是接口返回對const對象的引用。 – nothrow

回答

3

您可以將表封裝爲私有類型,在該對象中使用該類型的單個const實例,然後將相關的構造函數參數轉發給私有對象;這是有效的,因爲即使const對象在其構建期間也是非const

例如:

class MyClass { 
    const struct Tables { 
    double x[1000]; 
    double y[200]; 
    Tables(int i, double d) { 
     x[i] = d; 
     y[200 - i] = -d; 
    } 
    } tables; 
public: 
    MyClass(int i, double d) : tables(i, d) {} 
}; 
MyClass c(20, 5.5); 

的另一種技術是建立在一個短暫的可變數組,其壽命由構造的壽命界定的表,然後從初始化那些可變陣列const陣列。

使用C++ 11 std::array(因爲陣列類型不能被複制初始化):

class MyClass { 
    static std::array<double, 1000> buildArray(...) { 
     std::array<double, 1000> array; 
     ... // fill array 
     return array; 
    } 
    const std::array<double, 1000> mArray; 
public: 
    MyClass(...) : mArray(buildArray(...)) {} 
}; 

注意std::array是容易表達在C++ 03;它不依賴於任何C++ 11語言功能。

如果您擔心返回大型數組的開銷,那麼即使C++ 03編譯器也能夠優化大型數組返回。

+0

如果我理解正確,這個答案可以概括爲「查找/創建一個新的數組類型,通過賦值實現深度複製」,我正確嗎? – user3528438

+0

@ user3528438通過* initialization *。其實有更好的方法 - 我會更新我的答案。 – ecatmur

+0

我看到了新的答案。您是否嘗試使用「MyClass(int i,double d):tables(i,d){}」而不是「MyClass(int i,double d):tables(Tables(i,d)){}」來避免該結構的深層副本? – user3528438

1

我想你可以實現一個包含實際的非常量數組的類。這樣你可以很容易地在構造函數中計算值。

然後這個類只需要實現operator[]作爲一個數組。或者它也可以簡單地將一個const引用返回給數組。

實現例如:

#include <iostream> 
using namespace std; 

class const_array { 
    int *arr; 
    size_t size; 

public: 
    const_array(size_t size, int typ): size(size) { 
     arr = new int[size]; 
     size_t i; 
     int val = 0; 
     for (i=0; i<size; i++) { 
      val += typ; 
      arr[i] = val; 
     } 
    } 
    const_array(const const_array & src): size(src.size) { 
     arr = new int[size]; 
     size_t i; 
     for (i=0; i<size; i++) { 
      arr[i] = src.arr[i]; 
     } 
    } 
    ~const_array() { 
     delete[] arr; 
    } 

    const int * const getArray() const { 
     return arr; 
    } 
    int getSize() const { 
     return size; 
    } 

    const int& operator[](int i) { 
     return arr[i]; 
    } 
}; 

int main() { 
    const_array a(16, 4); 
    // int *arr = a.getArray(); error 
    const int *arr = a.getArray(); 
    int j = a[2]; 
    int k = arr[2]; 
    // int * pj = &(a[2]); error 
    const int * pj = &(a[2]); 
    const int * pk = &(arr[2]); 
    cout << "a[2]=" << j << " (" << pj << ") - a.getArray[2]=" 
     << j << " (" << pj << ")" << endl; 
    return 0; 
} 
+0

您能否向我解釋「const int * const getArray()const {return arr;}」中第三個「const」的含義? – user3528438

+0

第三個'const'表示成員函數不修改任何成員數據(實際上,這意味着它不會修改非可變成員數據)。 – frasnian

+0

在這同一行中,使用「const int * const」和「const int&」有什麼區別,是因爲後者允許「arr」作爲指針被修改? – user3528438