我的代码中有两种类型的结构变量初始化。
实施例
#include<iostream>
#include<string>
using namespace std;
struct Data{
int arr[5];
float x;
};
int main(){
struct Data d = {0};
struct Data d1 = {};
cout<<d.arr[0]<<d.x;
cout<<d1.arr[0]<<d1.x<<endl;
return 0;
}
我正在运行代码广告获取0 0 0 0作为我的输出。请帮帮我,两次初始化之间是否有任何区别。
答案 0 :(得分:7)
根据aggregate initialization的规则,这里的效果是相同的,即结构的所有成员都是value-initialized(zero-initialized这里是非类型的。) / p>
如果初始化程序子句的数量少于成员数
and bases (since C++17)
或初始化程序列表完全为空,则其余成员and bases (since C++17)
将按空列表初始化by their default initializers, if provided in the class definition, and otherwise (since C++14)
,具体如下:通常的列表初始化规则(使用默认构造函数执行非类类型和非聚合类的值初始化,以及聚合的聚合初始化)。如果引用类型的成员是其余成员之一,则该程序格式不正确。
更准确地说,
struct Data d = {0}; // initialize the 1st member of Data to 0, value-initialize(zero-initialize) the remaining members
struct Data d1 = {}; // value-initialize(zero-initialize) all the members of Data
请注意,整个故事的基础是Data
是aggregate type,其成员是非类型,否则行为会根据list initialization的规则发生变化。< / p>
答案 1 :(得分:0)
使用{}的默认初始化被定义为使用{}初始化每个成员。所以,通过做
struct Data d1 = {};
Data d1
初始化为{{},{}}
,即{{0, 0, 0, 0, 0}, 0.0}
,
0
和0.0
是int
和float
的默认值。
这就是你没有看到任何差异的原因。在你的情况下,他们两个总是做同样的事情。
在这些情况下存在差异:
1。)这是在{}
内提供初始化程序时变为必需:
struct X {
X(int);
};
X x1 {}; // error : empty initializer. X(int) states that an int is required to construct an X.
X x2 {0}; // OK
2。)零初始化禁止
的情况struct Test {
string name;
int year;
};
Test alpha0{0}; // Error. Because name in Test fails at zero-initialization.
Test alpha{}; // OK. Because name in Test is default-initialized with empty string "".
答案 2 :(得分:0)
在这种情况下结果相同,但在其他情况下不一定如此。
在这种情况下,您还没有提供ctor,因此您正在使用聚合初始化。这给出了空初始化列表的零初始化,并且你为非空的列表提供了0,所以两者的结果相同。
如果您提供了一个ctor,那么从两者中得到不同的结果将是微不足道的:
#include <iostream>
struct foo {
int f;
foo(int f = 5) : f(f) {}
friend std::ostream &operator<<(std::ostream &os, foo const &f) {
return os << f.f;
}
};
int main() {
foo f1{};
foo f2{0};
std::cout << "Empty init list: " << f1 << "\n";
std::cout << "zero init list: " << f2 << "\n";
}
虽然ctor是最明显的方法,但它不是唯一的方法。另一个明显的例子(仅限C ++ 11和更新版本):
struct foo {
int f = 5;
};
答案 3 :(得分:-2)
是的,有区别。在第一种情况下,您明确地将Data
(arr[0]
)的第一个成员初始化为零。在第二种情况下,你没有初始化任何东西,只是阅读那里发生的任何价值。在这种情况下,它也是零,但不能保证工作,特别是在更复杂的程序中。
初始化结构的所有成员始终是个好主意。考虑一下这个稍微修改过的程序版本,它应该能够清楚地发现:
#include<iostream>
#include<string>
using namespace std;
struct Data{
int arr[5];
float x;
};
int main(){
struct Data d = {1, 2, 3, 4, 5, 3.14f};
struct Data d1 = {};
cout<<d.arr[0]<<", "<<d.x<<", ";
cout<<d1.arr[0]<<", "<<d1.x<<endl;
return 0;
}
这将打印:
1, 3.14, 0, 0