为什么 C++构造函数对数组使用动态分配吗?
在我的课程笔记中给出了这两个例子。显然第一个是不允许的,是否有技术原因导致我无法在堆栈上分配?或者这是C++标准?
// Constructor may force dynamic allocation when initializating an array of objects.
Complex ac[10]; // complex array initialized to 0.0
for ( int i = 0; i < 10; i += 1 ) {
ac[i] = (Complex){ i, 2.0 } // disallowed
}
// MUST USE DYNAMIC ALLOCATION
Complex *ap[10]; // array of complex pointers
for ( int i = 0; i < 10; i += 1 ) {
ap[i] = new Complex( i, 2.0 ); // allowed
}
In my course notes these two examples are given. Apparently the first one is not allowed, is there a technical reason why I can't allocate on stack? Or is this the C++ standard?
// Constructor may force dynamic allocation when initializating an array of objects.
Complex ac[10]; // complex array initialized to 0.0
for ( int i = 0; i < 10; i += 1 ) {
ac[i] = (Complex){ i, 2.0 } // disallowed
}
// MUST USE DYNAMIC ALLOCATION
Complex *ap[10]; // array of complex pointers
for ( int i = 0; i < 10; i += 1 ) {
ap[i] = new Complex( i, 2.0 ); // allowed
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
第一个不是有效的语法。但假设您的 Complex 类有一个公共复制赋值运算符(隐式运算符可能没问题),那么以下内容应该没问题:
The first one is not valid syntax. But assuming your
Complex
class has a public copy-assignment operator (the implicit one should probably be fine), then the following should be fine:True,但这只是因为它使用了错误的语法。以下工作有效:
因此,该声明实际上是错误的(假设可以分配
Complex
,默认情况下可以) - 不需要动态分配。True, but only because it uses a wrong syntax. The following works:
So the claim is in fact wrong (assuming that
Complex
can be assigned to, which it by default can) – no dynamic allocation is needed.以下是完全允许的——你只是语法错误。您无法强制转换初始值设定项列表,但可以像调用函数一样调用构造函数。
The following is perfectly allowed -- you just had the wrong syntax. You can't cast initializer lists, but you can call constructors as though they are functions.
当然,您可以提供初始化列表中的所有值,
但是随着大小的增加,这很快就会变得非常笨拙。所以很自然地想要使用循环。
虽然独立初始化自动(通常相当于“堆栈上”)缓冲区中的元素并非不可能,但这并不容易。
问题是定义数组会导致立即调用构造函数。您必须定义一个 char 数组(没有构造函数),然后手动构造和销毁元素(使用放置 new 和显式析构函数调用)。这并不难,除非您想要异常安全,在这种情况下,极端情况很难处理。
如果允许您默认构造然后重新分配元素,那么这很简单,并且由其他答案涵盖。如果
Complex
有一个有效的赋值运算符,你应该这样做。You may of course provide all the values in an initializer-list, like
but this gets very unwieldy very quickly as the size increases. So it's natural to want to use a loop.
While it's not impossible to independently initialize elements in an automatic (which usually equates to "on stack") buffer, it's not at all easy.
The problem is that defining an array causes the constructor to be called immediately. You'd have to define a
char
array (which has no constructor), and then construct and destroy the elements manually (using placement new and explicit destructor calls). This isn't so hard unless you want exception safety, in which case the corner cases are very difficult to handle.If you're allowed to default-construct and then reassign the elements, it's easy, and covered by the other answers. If
Complex
has a working assignment operator, you should do this.没有这样的规则:构造函数必须动态分配数组。
是有效的。事实上,您应该尽可能避免动态数组。
There is no such rule that constructor must have dynamic allocation for array.
is valid. In fact you should avoid dynamic arrays, as much as you can.