背景:我坚持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风格数组的替代品。
答案 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;
}