我们有以下代码:
#include <iostream>
struct TStruct{
int x;
int y;
int * ptr;
TStruct( void ) : x( 0 ), y( 0 ), ptr( nullptr ) { }
};
int main(){
TStruct arr[100];
TStruct * arr2 = new TStruct[200];
// some code working with these arrays
for( int i = 0; i < 100; i ++ )
if( arr[i] . ptr != nullptr )
delete [] arr[i] . ptr;
for( int i = 0; i < 200; i ++ )
if( arr2[i] . ptr != nullptr )
delete [] arr2[i] . ptr;
delete [] arr2;
return 0;
}
这两个initialization
- arrays
和static
的{{1}}如何运作?它们是由dynamic
自动初始化还是必须通过循环它们并为每个TStruct成员设置值来手动初始化它们?
答案 0 :(得分:2)
TStruct
构造函数将使用您显示的代码调用300次。数组arr
中的每个元素一百次,为arr2
分配内存时二百次。
对于数组arr
,编译器生成用于调用构造函数的代码,当您使用new[]
时,运算符将确保调用构造函数。
答案 1 :(得分:2)
每个TStruct实例都将调用默认构造函数。 在您的代码段中,有300个实例和300个默认的构造函数调用。
在构造函数调用方面,由new
,new[]
创建的实例与堆栈上的“正常”创建之间没有区别。
在您的示例中,您创建了一个默认构造函数,每个实例都会调用它。
如果不存在这样的自定义默认构造函数,系统将创建自动生成的默认构造函数。生成的将调用每个数据元素的默认构造函数。
如果使用动态部分定义类,例如在问题中(使用new
来保留内存并将内存地址分配给指针),则需要注意指针值:将指针值设置为实例化时的NULL
/ nullptr
非常重要。
原因是,您(或使用该类的某人)可能突然将delete
应用于其实例的指针值。指针的默认值不是 null,而是内存中的随机地址。以默认的随机地址删除对象会导致意外行为或程序崩溃。
答案 2 :(得分:1)
这两个
initialization
-arrays
和static
的{{1}}如何运作?它们是由dynamic
自动初始化还是必须通过循环它们并为每个TStruct成员设置值来手动初始化它们?
两个语句都会为实例化的每个元素调用TStruct constructor
默认构造函数,您不需要手动手动。