复制非POD类型的构造函数和普通构造函数
Copy constructor and normal constructor for non-POD type
有这样的代码:
#include <iostream>
class KlasaNiePOD{
public:
int a;
~KlasaNiePOD(){}
};
int main() {
KlasaNiePOD obiekt1; // first case
std::cout << obiekt1.a << std::endl; // -1075234152
KlasaNiePOD obiekt2 = KlasaNiePOD(); // second case
std::cout << obiekt2.a << std::endl; // 0
return 0;
}
为什么在第一种情况下"a"没有初始化,而在第二种情况下它初始化了?不应该总是在非POD类中调用构造函数吗?
编辑:
来自组件的片段:
.globl main
.type main, @function
main:
.LFB960:
.cfi_startproc
.cfi_personality 0x0,__gxx_personality_v0
.cfi_lsda 0x0,.LLSDA960
pushl %ebp
.cfi_def_cfa_offset 8
movl %esp, %ebp
.cfi_offset 5, -8
.cfi_def_cfa_register 5
andl $-16, %esp
pushl %esi
pushl %ebx
subl $40, %esp
movl 28(%esp), %eax
movl %eax, 4(%esp)
movl $_ZSt4cout, (%esp) # std::cout << obiekt1.a << std::endl;
.LEHB0:
.cfi_escape 0x10,0x3,0x7,0x55,0x9,0xf0,0x1a,0x9,0xf8,0x22
.cfi_escape 0x10,0x6,0x7,0x55,0x9,0xf0,0x1a,0x9,0xfc,0x22
call _ZNSolsEi
movl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, 4(%esp)
movl %eax, (%esp)
call _ZNSolsEPFRSoS_E
.LEHE0:
movl $0, 24(%esp) # Here obiekt2.a = 0
movl 24(%esp), %eax
movl %eax, 4(%esp)
movl $_ZSt4cout, (%esp) # std::cout << obiekt2.a << std::endl;
.LEHB1:
call _ZNSolsEi
movl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, 4(%esp)
movl %eax, (%esp)
call _ZNSolsEPFRSoS_E
.LEHE1:
movl $0, %ebx
leal 24(%esp), %eax
movl %eax, (%esp)
call _ZN11KlasaNiePODD1Ev
leal 28(%esp), %eax
movl %eax, (%esp)
call _ZN11KlasaNiePODD1Ev
movl %ebx, %eax
addl $40, %esp
popl %ebx
popl %esi
movl %ebp, %esp
popl %ebp
ret
KlasaNiePOD obiekt1; // first case
这是默认初始化;由于它没有默认的构造函数,所以具有基本类型(包括数字类型)的成员是未初始化的。
KlasaNiePOD obiekt2 = KlasaNiePOD(); // second case
临时KlasaNiePOD()
是初始化的值;由于它没有默认的构造函数,所以具有数字类型的成员被初始化为零。
该标准定义了几种不同类型的初始化,取决于上下文。零初始化将所有成员设置为0(转换为适当的类型,因此指针将设置为null指针值,即使空指针不全是零位);不构造函数被调用。默认初始化调用默认构造函数,默认情况下不会执行任何操作。值初始化如果存在用户定义的构造函数,则调用默认构造函数,但是如果没有用户定义的构造函数。初始值设定项为的对象简单地对CCD_ 2(空列表)进行值初始化。具有静态的对象生存期在程序启动前初始化为零(始终);如果它有非平凡构造函数,稍后将调用其构造函数(但在进入main
之前)。未定义的所有其他对象初始化器默认初始化。
在您的代码中,obiekt1
是默认初始化的;在这种情况下,无操作(使成员未初始化)。obiekt2
通过复制初始化临时初始化的值;值初始化将CCD_ 6设置为0。(实际副本可能会进行优化,并进行值初始化直接发生在物体上。)
ISO 14882:2011(e)8.5.1:
聚合是一个没有用户提供的数组或类(第9条)构造函数(12.1),非静态数据没有大括号或等号成员(9.2),没有私有或受保护的非静态数据成员(第条11) ,没有基类(第10条),也没有虚拟函数(10.3)。
因此,您的类是一个集合。
KlasaNiePOD obiekt2 = KlasaNiePOD(); // second case
将调用聚合,最后调用值初始化,导致int初始化为零。
添加
KlasaNiePOD(){}
到您的类定义,您将看到0的设置将消失(因为这将使它不再是聚合)。
- "error: no matching function for call to"构造函数错误
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- C++定义构造函数使对象成为非 POD
- 我可以说服自动生成的构造函数将我的 POD 类成员归零吗?
- 在不使用默认构造函数的情况下声明 POD 结构时,会实例化什么?
- 初始化新对象时C++默认构造函数和 POD 问题
- 为什么具有已删除复制构造函数的结构不是 POD 类型
- 构造函数初始化列表中POD类型的初始化
- 非 pod 类型的布局(因为具有默认构造函数)
- 默认的构造函数和POD
- C++11中POD的构造函数要求
- 具有用户定义构造函数的普通和 POD 类型
- POD 类对象初始化是否需要构造函数
- (POD)结构上是否需要移动构造函数
- 默认构造函数、POD初始化和C++11中的隐式类型转换
- 对空的用户定义构造函数将如何初始化非静态非 POD 成员变量感到困惑
- 复制非POD类型的构造函数和普通构造函数
- 迭代器默认构造函数和POD成员初始化
- 从POD结构继承的类中默认构造函数的奇怪行为
- 在POD中强制默认初始化构造函数