class A
{
static int i;
A()
{
System.out.println(++i);
}
public static void main(String h[])
{
A obj[] = new A[30];
}
}
一个 obj[30] = 新的 A[30]; :- 这一行应该调用默认构造函数 30 次?
class A
{
static int i;
A()
{
System.out.println(++i);
}
public static void main(String h[])
{
A obj[] = new A[30];
}
}
一个 obj[30] = 新的 A[30]; :- 这一行应该调用默认构造函数 30 次?
线
A obj[30] = new A[30];
不调用构造函数A
。它创建了 30 个未实例化的引用A
;
要实例化 30 个对象引用,您可以使用:
A obj[] = { new A(), new A(), ..28 more ->
};
考虑到元素的数量,或者在这种情况下更好:
for (int i=0; i < obj.length; i++) {
obj[i] = new A();
}
注意,30
数组大小声明中的第一次使用是非法的。
A obj[30] = new A[30];
^
不,这一行根本不调用构造函数。它只是创建了 30 个元素的长数组类型A
。数组的每个元素都是null
.
没有办法完全按照您的意愿去做,但这里有两件事非常接近,都调用了默认构造函数 30 次:
A *obj = new A[30];
或者
A obj[30];
第一个答案将在堆上创建一个包含 30 个 A 对象的数组,并为每个对象调用默认构造函数。obj 可以传回给这个函数的调用者,因为它不在堆栈上。问题是,obj 不再具有 A[30] 的类型,因此 sizeof(obj) 将与原始问题中的代码不同。(请注意,obj 必须使用“delete []”,而不仅仅是“delete”。)
第二个答案将在堆栈上创建一个包含 30 个 A 对象的数组。现在编译器将理解 obj 有 30 个元素,并且 sizeof(obj) 将与您的问题相同。但是,obj 只能在这个函数(或它调用的函数)中使用,因为一旦函数返回,它将从堆栈中消除,在此过程中调用 30 个析构函数。(它只是一个局部变量。)
对于 C++(或任何好的面向对象语言),创建对象总是意味着分配空间和调用构造函数。否则,你真的没有一个有用的对象。因此,当以任何受支持的方式(局部变量或 C++ 的“新”)创建对象时,它总是为您创建并现在可以访问的每个对象调用默认构造函数。(请注意,如果没有默认构造函数,那么两个答案都不会编译!)