Nat*_*man 73 c++ array-initialize initialization c++03
我在C++中有以下类:
class a {
const int b[2];
// other stuff follows
// and here's the constructor
a(void);
}
Run Code Online (Sandbox Code Playgroud)
问题是,如何在初始化列表中初始化b,因为我无法在构造函数体内初始化它,因为b是const?
这不起作用:
a::a(void) :
b([2,3])
{
// other initialization stuff
}
Run Code Online (Sandbox Code Playgroud)
编辑:这个例子就是我可以b为不同的实例设置不同的值,但是已知这些值在实例的生命周期内是不变的.
Fle*_*exo 72
使用C++ 11,这个问题的答案现在已经改变了,你实际上可以做到:
struct a {
const int b[2];
// other bits follow
// and here's the constructor
a();
};
a::a() :
b{2,3}
{
// other constructor work
}
int main() {
a a;
}
Run Code Online (Sandbox Code Playgroud)
Wei*_*g L 32
像其他人说的那样,ISO C++不支持这一点.但你可以解决它.只需使用std :: vector.
int* a = new int[N];
// fill a
class C {
const std::vector<int> v;
public:
C():v(a, a+N) {}
};
Run Code Online (Sandbox Code Playgroud)
Luc*_*lle 25
目前的标准是不可能的.我相信你能够做到这一点的C++ 0x使用初始化列表(见在的C++ 0x略看,由Bjarne Stroustrup的,有关初始化列表和其他不错的C++ 0x功能的更多信息).
小智 12
std::vector使用堆.Geez,这只是为了进行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;
}
Run Code Online (Sandbox Code Playgroud)
ConstFixedSizeArrayFiller并且ConstFixedSizeArray可以重复使用.
第一个允许在初始化数组时进行运行时边界检查(与向量相同),稍后可以const在此初始化之后进行.
第二个允许将数组分配到另一个对象中,该对象可以在堆上,或者只是堆栈(如果该对象所在的位置).从堆中分配时不浪费时间.它还对数组执行编译时const检查.
b_filler是一个提供初始化值的微小私有类.使用模板参数在编译时检查数组的大小,因此不可能超出范围.
我敢肯定有更多奇特的方法可以修改它.这是一个初步的刺.我认为你几乎可以弥补任何编译器的类缺点.
ISO标准C++不允许您这样做.如果是这样,语法可能是:
a::a(void) :
b({2,3})
{
// other initialization stuff
}
Run Code Online (Sandbox Code Playgroud)
或类似的规定.从你的问题来看,它实际上听起来像你想要的是一个常数类(又名静态)成员,即数组.C++确实允许你这样做.像这样:
#include <iostream>
class A
{
public:
A();
static const int a[2];
};
const int A::a[2] = {0, 1};
A::A()
{
}
int main (int argc, char * const argv[])
{
std::cout << "A::a => " << A::a[0] << ", " << A::a[1] << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
A::a => 0, 1
Run Code Online (Sandbox Code Playgroud)
当然,因为这是一个静态类成员,它对于类A的每个实例都是相同的.如果那不是你想要的,即你希望A的每个实例在数组中都有不同的元素值,那么你就是在做尝试使数组const开始的错误.你应该这样做:
#include <iostream>
class A
{
public:
A();
int a[2];
};
A::A()
{
a[0] = 9; // or some calculation
a[1] = 10; // or some calculation
}
int main (int argc, char * const argv[])
{
A v;
std::cout << "v.a => " << v.a[0] << ", " << v.a[1] << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)