在 C++ 中的类初始值设定项中初始化 const 数组
我在 C++ 中有以下类:
class a {
const int b[2];
// other stuff follows
// and here's the constructor
a(void);
}
问题是,如何在初始化列表中初始化 b,因为我无法在构造函数的函数体内初始化它,因为 b 是 const >?
这不起作用:
a::a(void) :
b([2,3])
{
// other initialization stuff
}
编辑:恰当的例子是,我可以为不同的实例设置不同的 b 值,但已知这些值在实例的生命周期内是恒定的。
I have the following class in C++:
class a {
const int b[2];
// other stuff follows
// and here's the constructor
a(void);
}
The question is, how do I initialize b in the initialization list, given that I can't initialize it inside the body of the function of the constructor, because b is const
?
This doesn't work:
a::a(void) :
b([2,3])
{
// other initialization stuff
}
Edit: The case in point is when I can have different values for b
for different instances, but the values are known to be constant for the lifetime of the instance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
使用 C++11,这个问题的答案现在已经改变,您实际上可以这样做:
With C++11 the answer to this question has now changed and you can in fact do:
正如其他人所说,ISO C++ 不支持这一点。 但你可以解决它。 只需使用 std::vector 即可。
Like the others said, ISO C++ doesn't support that. But you can workaround it. Just use std::vector instead.
在现行标准中这是不可能的。 我相信您将能够使用初始化列表在 C++0x 中执行此操作(请参阅简要介绍参见 C++0x,作者:Bjarne Stroustrup,了解有关初始值设定项列表和其他不错的 C++0x 功能的更多信息)。
It is not possible in the current standard. I believe you'll be able to do this in C++0x using initializer lists (see A Brief Look at C++0x, by Bjarne Stroustrup, for more information about initializer lists and other nice C++0x features).
std::vector
使用堆。 天哪,仅仅为了 const 健全性检查就太浪费了。 std::vector 的要点是运行时的动态增长,而不是应在编译时完成的任何旧语法检查。 如果您不打算增长,那么创建一个类来包装普通数组。ConstFixedSizeArrayFiller
和ConstFixedSizeArray
是可重用的。第一个允许在初始化数组时进行运行时边界检查(与向量可能相同),初始化后数组可以变成 const。
第二个允许将数组分配到另一个对象内部,该对象可以位于堆上,也可以简单地位于堆栈上(如果对象所在的位置就是堆栈)。 从堆中分配不会浪费时间。 它还对数组执行编译时常量检查。
b_filler
是一个微小的私有类,用于提供初始化值。 数组的大小在编译时使用模板参数进行检查,因此不会超出范围。我确信还有更奇特的方法可以修改它。 这是初步的刺击。 我认为你几乎可以用类来弥补编译器的任何缺点。
std::vector
uses the heap. Geez, what a waste that would be just for the sake of aconst
sanity-check. The point ofstd::vector
is dynamic growth at run-time, not any old syntax checking that should be done at compile-time. If you're not going to grow then create a class to wrap a normal array.ConstFixedSizeArrayFiller
andConstFixedSizeArray
are reusable.The first allows run-time bounds checking while initializing the array (same as a vector might), which can later become
const
after this initialization.The second allows the array to be allocated inside another object, which could be on the heap or simply the stack if that's where the object is. There's no waste of time allocating from the heap. It also performs compile-time const checking on the array.
b_filler
is a tiny private class to provide the initialization values. The size of the array is checked at compile-time with the template arguments, so there's no chance of going out of bounds.I'm sure there are more exotic ways to modify this. This is an initial stab. I think you can pretty much make up for any of the compiler's shortcoming with classes.
ISO 标准 C++ 不允许您这样做。 如果是的话,语法可能是:
或者类似的东西。 从你的问题来看,实际上听起来你想要的是一个常量类(又名静态)成员,即数组。 C++ 确实可以让你这样做。 像这样:
输出是:
现在当然,因为这是一个静态类成员,所以对于类 A 的每个实例都是相同的。如果这不是您想要的,即您希望 A 的每个实例在array a 那么你就犯了一个错误,试图让数组成为 const 。 你应该这样做:
ISO standard C++ doesn't let you do this. If it did, the syntax would probably be:
Or something along those lines. From your question it actually sounds like what you want is a constant class (aka static) member that is the array. C++ does let you do this. Like so:
The output being:
Now of course since this is a static class member it is the same for every instance of class A. If that is not what you want, ie you want each instance of A to have different element values in the array a then you're making the mistake of trying to make the array const to begin with. You should just be doing this:
当我有一个常量数组时,它总是以静态方式完成。 如果您可以接受这一点,则该代码应该可以编译并运行。
Where I've a constant array, it's always been done as static. If you can accept that, this code should compile and run.
你不能从初始化列表中做到这一点,
看看这个:
http ://www.cprogramming.com/tutorial/initialization-lists-c++.html
:)
You can't do that from the initialization list,
Have a look at this:
http://www.cprogramming.com/tutorial/initialization-lists-c++.html
:)
不使用
std::vector
堆的解决方案是使用boost::array
,尽管您无法直接在构造函数中初始化数组成员。A solution without using the heap with
std::vector
is to useboost::array
, though you can't initialize array members directly in the constructor.通过访问器函数模拟 const 数组怎么样? 它是非静态的(如您所要求的),并且不需要 stl 或任何其他库:
因为 a::privateB 是私有的,所以它在 a:: 之外实际上是常量,并且您可以像数组一样访问它,例如
如果您愿意使用一对类,您还可以保护 privateB 免受成员函数的影响。 这可以通过继承来完成; 但我想我更喜欢 John Harrison 的 comp.lang。使用 const 类的 c++ post。
How about emulating a const array via an accessor function? It's non-static (as you requested), and it doesn't require stl or any other library:
Because a::privateB is private, it is effectively constant outside a::, and you can access it similar to an array, e.g.
If you are willing to use a pair of classes, you could additionally protect privateB from member functions. This could be done by inheriting a; but I think I prefer John Harrison's comp.lang.c++ post using a const class.
有趣的是,在 C# 中,关键字 const 可以转换为 C++ 的 static const,而不是 readonly,readonly 只能在构造函数和初始化时设置,即使是非常量,例如:
我同意,如果你有一个 const 预定义数组你不妨将其设为静态。
此时您可以使用这个有趣的语法:
但是,我没有找到绕过常量“10”的方法。 原因很明显,它需要它知道如何执行对数组的访问。 一种可能的替代方法是使用 #define,但我不喜欢这种方法,并且我在标头末尾添加 #undef,并在 CPP 处添加注释以进行编辑,以防发生更改。
interestingly, in C# you have the keyword const that translates to C++'s static const, as opposed to readonly which can be only set at constructors and initializations, even by non-constants, ex:
I agree, if you have a const pre-defined array you might as well make it static.
At that point you can use this interesting syntax:
however, I did not find a way around the constant '10'. The reason is clear though, it needs it to know how to perform accessing to the array. A possible alternative is to use #define, but I dislike that method and I #undef at the end of the header, with a comment to edit there at CPP as well in case if a change.