7

我的代码中有两种类型的结构变量初始化。

例子

#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 作为我的输出。请帮助我,这两种初始化之间有什么区别。

4

4 回答 4

7

根据聚合初始化的规则,这里的效果是一样的,即结构体的所有成员都会被值初始化(这里是对非类类型进行零初始化)。

如果初始化子句的数量少于成员的数量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是一个聚合类型,并且它的成员是非类类型,否则行为会根据列表初始化的规则而改变。

于 2016-11-23T06:09:41.580 回答
0

使用 {}的默认初始化定义为使用 {} 对每个成员进行初始化。所以,通过做

struct Data d1 = {};

Data d1被初始化为{{},{}},即{{0, 0, 0, 0, 0}, 0.0}

as0和是和0.0的默认值。intfloat

这就是您看不到任何差异的原因。在您的情况下,他们俩总是做同样的事情。

不同之处在于这些情况:

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 "".
于 2016-11-23T06:25:57.503 回答
0

在这种情况下结果是相同的,但在其他情况下不一定如此。

在这种情况下,您没有提供 ctor,因此您正在使用聚合初始化。这为空初始化列表提供了零初始化,并且您为非空列表提供了 0,因此两者的结果相同。

如果您提供了一个演员,那么从两者中获得不同的结果将是微不足道的:

#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";
}

尽管演员是最明显的方法,但它不是唯一的。对于另一个明显的示例(仅限 C++11 和更高版本):

struct foo { 
    int f = 5;
};
于 2016-11-23T06:26:27.790 回答
-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
于 2016-11-23T06:19:54.500 回答