如何计算初始化const数组(make const查找表)?

时间:2015-01-16 14:18:30

标签: c++ c++11

背景:我坚持arm-arago-linux-gnueabi-g++ (GCC) 4.3.3。虽然也欢迎需要C ++ 11或更高版本的答案,但请在C ++ 03之后明确表达任何语言要求。

对象的构造函数将值填充到算法使用的表中。

由于这些表没有改变而且不应该改变,我希望它们是const,我该怎么做?

难度#1,这些值是计算生成的,我不想在源文件中硬编码。

难度#2,计算有时取决于仅在运行时可用的输入。

难度#3,我不知道为什么但是我不希望数组是静态的,即使所有对象的值可能相同(值不依赖于运行时输入的情况)。 / p>

难度#4,它是一个数组,所以C ++ 03中的初始化列表不起作用。

EDIT1: 在这篇文章发表几周后,我发现当std :: array不可用时,std :: array和std :: vector都是C风格数组的替代品。

2 个答案:

答案 0 :(得分: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编译器也能够优化大型数组返回。

答案 1 :(得分:1)

我认为你可以实现一个包含实际非const数组的类。这样,您可以轻松地在构造函数中计算值。

然后这个类只需实现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;
}