在C++中声明静态/动态数组会自动调用每个元素的默认构造函数

Does declaring a static/dynamic array in C++ call default constructor on each element automatically?

本文关键字:调用 元素 构造函数 默认 声明 C++ 静态 数组 动态      更新时间:2023-10-16

问题在主题中。我也很好奇,原始类型和对象的行为是否不同?

这是一个很难准确回答的问题。它被问了很多次(也被回答了很多次),但我找不到确切的副本。

首先,声明数组不会分配任何存储,也不会导致执行任何构造函数。也许您的意思是定义分配一个数组。

静态存储(任何块外)中定义的数组,无论其类型如何,其存储都会填充零。

自动存储(块内)中定义的数组被分配未初始化的内存。

通过分配动态存储(使用new[])创建的阵列将分配未初始化的内存。

不管存储分配的方法如何,数组都是default-initialised。这意味着什么在n3797 S8.5/7:中有定义

默认初始化T类型的对象意味着:
--如果T是一个(可能是cv限定的)类类型(第9条),则调用T的默认构造函数(12.1)(如果T没有默认构造函数或重载解析(13.3)导致模糊性或在从初始化的上下文中被删除或不可访问的函数中)
--如果T是数组类型,则默认初始化每个元素
--否则,不执行初始化。

换句话说,类类型的数组在每个元素上都调用了它们的默认构造函数,而其他元素则保持原样

另见/12:

如果没有为对象指定初始值设定项,则默认初始化该对象;如果不执行初始化,则具有自动或动态存储持续时间的对象具有不确定的值。

如果在数组定义中添加初始化,所有这些都会被忽略,但我们将把它留给另一个问题。

让我们举一个例子。

struct Object
{
    Object(){
        std::cout << "new object is created";
    }
}
Object object1; // contructor is called here
Object object2; // and here
std::list<Object> my_list = {object1,object2}; //step 2

在步骤2中,您没有创建Object类型的新对象,只是将它们插入my_list中。注意:在数组中插入会导致类似的行为。

关于第二个问题,基元类型是POD(即Plain Old Data)类型,根据定义,它不能具有用户定义的构造函数。

是的,数组的所有元素都已默认初始化(调用对象的默认构造函数,或对基元不确定(除非也进行了零初始化,在这种情况下,基元设置为零)。

但是,有些类没有指定默认构造函数。在这些情况下,在不初始化数组的情况下,就不能拥有它们的数组,因为数组将无法默认初始化对象。您必须使用不同的集合,例如vector