std::vector
使用堆。天哪,这只是为了进行const
健全性检查而造成的浪费。重点std::vector
是运行时的动态增长,而不是任何应该在编译时进行的旧语法检查。如果你不打算增长,那么创建一个类来包装一个普通数组。
#include <stdio.h>
template <class Type, size_t MaxLength>
class ConstFixedSizeArrayFiller {
private:
size_t length;
public:
ConstFixedSizeArrayFiller() : length(0) {
}
virtual ~ConstFixedSizeArrayFiller() {
}
virtual void Fill(Type *array) = 0;
protected:
void add_element(Type *array, const Type & element)
{
if(length >= MaxLength) {
// todo: throw more appropriate out-of-bounds exception
throw 0;
}
array[length] = element;
length++;
}
};
template <class Type, size_t Length>
class ConstFixedSizeArray {
private:
Type array[Length];
public:
explicit ConstFixedSizeArray(
ConstFixedSizeArrayFiller<Type, Length> & filler
) {
filler.Fill(array);
}
const Type *Array() const {
return array;
}
size_t ArrayLength() const {
return Length;
}
};
class a {
private:
class b_filler : public ConstFixedSizeArrayFiller<int, 2> {
public:
virtual ~b_filler() {
}
virtual void Fill(int *array) {
add_element(array, 87);
add_element(array, 96);
}
};
const ConstFixedSizeArray<int, 2> b;
public:
a(void) : b(b_filler()) {
}
void print_items() {
size_t i;
for(i = 0; i < b.ArrayLength(); i++)
{
printf("%d\n", b.Array()[i]);
}
}
};
int main()
{
a x;
x.print_items();
return 0;
}
ConstFixedSizeArrayFiller
并且ConstFixedSizeArray
可以重复使用。
第一个允许在初始化数组时进行运行时边界检查(与向量可能相同),稍后可以const
在此初始化之后进行。
第二个允许将数组分配在另一个对象内部,该对象可以在堆上,如果对象所在的位置,则可以简单地在堆栈上。从堆中分配不会浪费时间。它还对数组执行编译时常量检查。
b_filler
是一个提供初始化值的小型私有类。数组的大小在编译时使用模板参数进行检查,因此不会超出范围。
我敢肯定有更多奇特的方法来修改它。这是一个初步的刺。我认为您几乎可以弥补编译器在类方面的任何缺点。