2

在我的课程笔记中给出了这两个例子。显然第一个是不允许的,我不能在堆栈上分配是否有技术原因?还是这是 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
    }
4

5 回答 5

7

第一个不是有效的语法。但是假设你的Complex班级有一个公共的复制赋值运算符(隐式的应该没问题),那么以下应该没问题:

Complex ac[10];             // complex array initialized to 0.0
for ( int i = 0; i < 10; i += 1 ) {
     ac[i] = Complex( i, 2.0 );
}
于 2011-07-18T13:35:35.433 回答
6

显然第一个是不允许的

没错,但这只是因为它使用了错误的语法。以下作品:

ac[i] = Complex(i, 2.0);

所以这个说法实际上是错误的(假设Complex可以分配,默认情况下可以)——不需要动态分配。

于 2011-07-18T13:35:37.377 回答
2

以下是完全允许的——你只是有错误的语法。您不能强制转换初始值设定项列表,但您可以调用构造函数,就好像它们是函数一样。

Complex ac[10];  // calls default constructor for each element
for ( int i = 0; i < 10; i += 1 ) {
     ac[i] = Complex(i, 2.0);  // constructs a temporary,
                               // then uses the assignment operator
}
于 2011-07-18T13:34:50.827 回答
1

您当然可以在初始化列表中提供所有值,例如

Complex ac[] = { Complex(0, 2.0), Complex(1, 2.0), /* and so on */ };

但是随着尺寸的增加,这会很快变得非常笨拙。所以很自然地想要使用循环。

虽然在自动(通常等同于“堆栈”)缓冲区中独立初始化元素并非不可能,但这并不容易。

问题是定义数组会导致立即调用构造函数。您必须定义一个char数组(没有构造函数),然后手动构造和销毁元素(使用放置 new 和显式析构函数调用)。除非您想要异常安全,否则这并不难,在这种情况下,极端情况很难处理。

如果您被允许默认构造然后重新分配元素,这很容易,并且被其他答案所涵盖。如果Complex有一个工作赋值运算符,你应该这样做。

于 2011-07-18T13:37:14.160 回答
0

没有这样的规则,即构造函数必须对数组进行动态分配。

ac[i] = Complex( i, 2.0 );

已验证。事实上,您应该尽可能避免使用动态数组。

于 2011-07-18T13:37:11.547 回答