几年前我读到使用{}和{0}来初始化POD在c ++中有一些细微的差别,其中一个可以在你的代码中引入悲观化。
D3D11_TEXTURE2D_DESC dsd = {};
D3D11_TEXTURE2D_DESC dsd2 = { 0 }:
虽然我知道{0}肯定是从c继承而且{}是c ++ 11中引入的东西,但两者都应该在编译期间被转换为同一个memset()调用:
memset(&dsd, 0, sizeof(dsd));
然而,2个大括号初始化样式中的一个做了内存初始化未对齐的事情,是否有人关心哪种风格更好以及为什么?
答案 0 :(得分:6)
您引用的语法称为aggregate initialization。
如果初始化程序子句的数量小于成员数或初始化程序列表完全为空,则其余成员将进行值初始化
由于POD的值初始化与零初始化相同,因此您显示的两种语法之间没有区别。
甚至在C ++ 11之前就是这种情况 - 空的初始化列表不是它引入的东西。从C ++ 11开始,非POD也允许使用语法。聚合初始化现在是这个新列表初始化的特例。
答案 1 :(得分:-7)
两个版本都是“在C ++ 11中引入的东西”。 Brace初始化是“只是”一种调用构造函数的方法。例如。 D3D11_TEXTURE2D_DESC dsd = {};
调用默认构造函数,而D3D11_TEXTURE2D_DESC dsd2 = { 0 };
调用一个,可以使用const int
作为唯一参数调用。除非你的一个构造函数这样做,否则它们都不会转换为类似于memset(&dsd, 0, sizeof(dsd));
的任何东西。
如果你有隐式声明的默认构造函数,它只会为struct
的每个元素调用默认构造函数。内置类型的默认构造函数不执行任何操作,因此内存不会设置为零。
对于那些没有定义构造函数且只有公共成员的struct
个,以及一些可以归结为C struct
的更多限制,你也得到aggregate initialization。这基本上是你期望来自C的。无论如何,D3D11_TEXTURE2D_DESC dsd2 = { 0 };
不等同于memset(&dsd, 0, sizeof(dsd));
,因为编译器可能出于任何原因向类添加填充,当然,还有字段的类型可能会在其构造函数中实现完全不同的东西。
好的,现在哪个更好,当然取决于你想要达到的目标。如果您正在处理C struct
,我更喜欢第二个,因为您不会获得未初始化的值。但请忘记关于memset()
等的任何假设。请改为查看构造函数。