为什么C ++构造函数必须使用数组的动态分配?

时间:2011-07-18 13:31:53

标签: c++ object dynamic-arrays

在我的课程中注意到这两个例子。显然第一个是不被允许的,是否有技术原因导致我无法在堆栈上分配?或者这是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
    }

5 个答案:

答案 0 :(得分: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 );
}

答案 1 :(得分:6)

  

显然第一个是不允许的

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

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

因此声明实际上是错误的(假设可以分配Complex,默认情况下可以) - 不需要动态分配。

答案 2 :(得分: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
}

答案 3 :(得分:1)

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

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

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

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

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

如果您被允许默认构造然后重新分配元素,那么它很容易,并且被其他答案覆盖。如果Complex有工作分配运算符,则应执行此操作。

答案 4 :(得分:0)

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

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

有效。事实上,你应该尽可能地避免使用动态数组。