在C++中声明静态/动态数组会自动调用每个元素的默认构造函数
Does declaring a static/dynamic array in C++ call default constructor on each element automatically?
问题在主题中。我也很好奇,原始类型和对象的行为是否不同?
这是一个很难准确回答的问题。它被问了很多次(也被回答了很多次),但我找不到确切的副本。
首先,声明数组不会分配任何存储,也不会导致执行任何构造函数。也许您的意思是定义的分配一个数组。
静态存储(任何块外)中定义的数组,无论其类型如何,其存储都会填充零。
自动存储(块内)中定义的数组被分配未初始化的内存。
通过分配动态存储(使用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
。
- 如何为 std::vector 分配内存,然后稍后为某些元素调用构造函数?
- C++:带有大括号初始化列表的函数调用表达式 - 标准是否规定在单个元素列表的微不足道的情况下忽略大括号?
- 使用并行参数向量调用元素向量的成员函数
- 调用 erase() 函数是否也会在擦除元素之前更改迭代器值?
- 为什么只有当我的容器有超过 32 个元素时才由 std::sort 调用交换?
- 调用QVector::保留即使不知道确切的元素数量?
- 如何在不迭代的情况下对数组中的每个元素调用方法
- 如何为包含最多N个元素的std::multiset调用最大数量分配
- 尝试将参数包的第一个元素作为函数调用,并将包的其余部分作为参数传递给它
- C++测试程序中的非法系统调用(对角矩阵元素程序的总和)
- 为什么 delete[] 不等同于 C++ 中为每个元素调用 delete?
- C++为每个元素调用任意函数
- 为什么只有在向量中已经有一个元素时才调用移动构造函数?
- Cython通过vdMul调用MKL在元素乘法上崩溃
- 如何部分专业化功能以用元组元素作为参数调用功能
- C ++尝试访问映射中的元素会给我一个不匹配的函数调用错误
- 在不调用构造函数的情况下创建 Vector 元素
- C++ 对矢量元素的调用函数,派生自矢量的基类
- 在父类的构造函数中调用元素对象的构造函数
- Delete[]未调用元素析构函数