我写了以下代码片段:
void foo()
{
struct _bar_
{
int a;
} bar;
cout << "Value of a is " << bar.a;
}
并使用g ++ 4.2.1(Mac)进行编译。输出为“a的值为0”。
是否可以说c ++中结构的数据成员默认是初始化的(与c相比)?或者观察到的结果是巧合吗?
我可以想象c ++中的结构有一个默认构造函数(因为结构和类在c ++中几乎相同),这可以解释为什么bar的数据成员a初始化为零。
答案 0 :(得分:47)
简单的答案是肯定的 它有一个默认的构造函数。
注意:struct和class是相同的(除了访问说明符的默认状态)。
但它是否初始化成员将取决于如何声明实际对象。在您的示例中,没有成员未初始化且具有不确定的值。
void func()
{
_bar_ a; // Members are NOT initialized.
_bar_ b = _bar_(); // Members are zero-initialized
// From C++14
_bar_ c{}; // New Brace initializer (Members are zero-initialized)
_bar_* aP = new _bar_; // Members are NOT initialized.
_bar_* bP = new _bar_(); // Members are zero-initialized
// From C++14
_bar_ cP = new _bar_{}; // New Brace initializer (Members are zero-initialized)
}
// static storage duration objects
// i.e. objects at the global scope.
_bar_ c; // Members are zero-initialized.
8.5 Initializers [dcl.init]
第4-10段的标准中详细说明了具体细节。但以下是对这种情况的简单总结。
没有用户定义构造函数的结构具有编译器生成的构造函数。但它的作用取决于它是如何使用的,它将默认初始化其成员(对于POD类型通常没有)或者它可能零初始化其成员(对于POD通常意味着将其成员设置为零)。
PS。不要使用_
作为类型名称中的第一个字符。你会遇到问题。
答案 1 :(得分:10)
是否可以说c ++中结构的数据成员默认是初始化的(与c相比)?或者观察到的结果是巧合吗?
这是巧合。
您的代码调用未定义的行为;除非您明确将成员设置为0
,否则它们可以是任何内容。
答案 2 :(得分:3)
不是答案,但你可能会认为......如果你想尝试一下:
void foo() {
struct test {
int value;
} x;
std::cout << x.value << std::endl;
x.value = 1000;
}
int main() {
foo();
foo();
}
在您的示例中,内存在创建变量之前已经具有0
值,因此您可以将其称为幸运巧合(事实上,某些操作系统会将所有内存清零在开始一个进程之前,这意味着0很可能在一个小的短程序中查找...),前面的代码将调用该函数两次,第一次调用的内存将在第二次调用中重用,很可能第二次它会打印1000.但是请注意,该值仍未定义,并且此测试可能显示或未显示预期结果(即编译器可以执行许多操作并生成不同的结果。 ..)
答案 3 :(得分:1)
默认情况下,的成员变量不会初始化。就像一个类(因为结构与类完全相同,只有在结构中,成员默认是公共的)。
答案 4 :(得分:0)
不要依赖此功能,这是非标准的
只需添加
foo() : a() {}
我不记得gcc 4.2的确切状态(我认为它太旧了)但如果您使用的是C ++ 11,则可以执行以下操作
foo()=default;