2016-11-23 83 views
7

我有两种类型的结构变量初始化在我的代码中。结构数据d = {0}和结构数据d = {}

#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

一个是初始化列表,你必须等于对方只是一个空的初始化列表。 –

+0

你期望在每个内部有什么?你不应该像那样初始化你的结构。你需要访问结构中的每个东西并初始化它。可能有一个函数需要一个结构,并有一个for循环,它将数组中的所有内容都初始化为0,并将您的x初始化为0 –

+0

@Danh不是一个混蛋。将问题标记为“c”,因为它涉及到c和C++共有的语法,但这不是“垃圾邮件”。 – djechlin

回答

7

aggregate initialization规则,效果这里同样,即该结构的所有成员将value-initializedzero-initialized这里用于非类类型)。

如果初始化子句的数目是小于成员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 

注意,整个故事是基于Dataaggregate type和它的成员都是非类类型,否则行为将根据规则改变list initialization

+1

我认为值得一提的是'数据'有构造函数 – Danh

+1

如果'Data'的第一个成员是类类型,那么也会有区别 –

-2

是的,有区别。在第一种情况下,您明确将Dataarr[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 
+0

你的程序应该说明什么? –

0

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

struct Data d1 = {}; 

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

00.0intfloat RESP默认值。

这就是您没有看到任何区别的原因。他们两个总是在你的情况下做同样的事情。

区别在于在这种情况下:

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 "". 
0

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

在这种情况下,您还没有提供ctor,因此您正在使用聚合初始化。这为empty-init-list提供了零初始化,并且你为非空的列表提供了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; 
};