【发布时间】:2011-04-17 17:14:48
【问题描述】:
当我使用初始化列表时:
struct Struct {
Struct() : memberVariable() {}
int memberVariable;
};
原始类型(int、bool、float、enum、指针)成员变量是默认初始化的。它获得实现的值是定义的还是所有实现都相同?
【问题讨论】:
标签: c++ initialization
当我使用初始化列表时:
struct Struct {
Struct() : memberVariable() {}
int memberVariable;
};
原始类型(int、bool、float、enum、指针)成员变量是默认初始化的。它获得实现的值是定义的还是所有实现都相同?
【问题讨论】:
标签: c++ initialization
像 int 这样的原生类型通常得到garbage value,例如。无论发生在创建它的内存区域中的什么。但是这在标准中没有定义,它也可能被初始化为 0,这在例如。调试构建。
编辑。但基本上,你永远不应该相信一个未初始化的变量来保存特定的东西。始终自己定义价值观。
【讨论】:
memberVariable(),它会初始化它。
标准说 (8.5/5)
默认初始化 T 类型的对象意味着:
——如果 T 是非 POD 类类型(第 9 条),则调用 T 的默认构造函数(如果没有可访问的默认构造函数,则初始化是非良构的);
——如果 T 是一个数组类型,每个元素都是默认初始化的;
—否则,对象被零初始化。
.
对 T 类型的对象进行值初始化意味着:
——如果 T 是具有用户声明的构造函数 (12.1) 的类类型(第 9 条),则调用 T 的默认构造函数(如果 T 没有可访问的默认构造函数,则初始化是非良构的);
——如果 T 是没有用户声明的构造函数的非联合类类型,则 T 的每个非静态数据成员和基类组件都是值初始化的;
——如果T是一个数组类型,那么每个元素都是值初始化的;
——否则,对象被零初始化
.
它获得的值是实现定义的还是所有实现都相同?
因此,所有实现的值都是相同的。
Struct 是非 POD 类型所以
Struct *a =new Struct; // default initialization
//memberVariable will be initialized to 0 because if T is a non-POD class type
//the default constructor for T is called
Struct *b = new Struct(); //value initializes Struct, which calls the default ctor.
//memberVariable will be initialized to 0 in this case also.
编辑:
@Johannes 注意到原始类型(int、bool、float、enum、指针)成员变量是 value-initialized 而不是 default initialized。
【讨论】:
— otherwise, the object is zero-initialized。 6 To default-initialize an object of type T means:是错误的。正确的句子是— otherwise, no initialization is performed.
对于原始类型,默认初始化表示对象被初始化为适合该类型的 0、0.0 或 NULL。
编辑:以上对 C++98 有效。在 C++03 中,这些术语得到了一些重新定义。现在,使用() 的初始化器(这在语法上只对成员对象可能)会导致值初始化,这对于原始类型意味着存储适当的值0、0.0 或NULL。
【讨论】:
memberVariable 被值初始化,效果完全相同。
memerVariable 是没有用户声明的构造函数的非 POD,则默认初始化不会初始化其成员,而值初始化将初始化它们。解释默认初始化的工作原理使人们(包括提问者,他们显然不知道)相信memberVariable 是默认初始化的,而实际上它是值初始化的。
0
如果您在原语上调用(),效果与分配默认值相同,如果它是静态的。
【讨论】:
int foo() { return 0; } 保证返回0?
int() 产生 0(键入为 int),因此它实际上与 return 0; 相同。
这取决于你如何实例化一个类,如果你使用 ClassName(),POD 类默认初始化为零,因为非 POD 类默认构造函数被调用,但如果你使用 ClassName,没有括号,则不会发生默认初始化。
【讨论】:
Struct::Struct(),它将同时用于new Struct 和new Struct()。
你说的不对。该对象不是默认初始化的,而是值初始化的。而且它的价值是明确的
int = 0,
bool = false,
float = 0.0f,
enum = (enum type)0,
pointer = null pointer
pointer to member = null member pointer
请注意,零在任何枚举的值范围内,即使它不包含具有该值的显式枚举数,因此将枚举变量初始化为该值是安全的。
特别是对于指向数据成员的指针,实际使用的表示不是全零位。在至少 GCC 和 Clang 使用的所谓 C++ Itanium ABI 中,指向数据成员的指针具有全一位空表示。
【讨论】:
int 不是非 POD 类类型。
Struct 作为一个整体,这当然是一种非 POD 类型。子对象的值已初始化。
C++TC1 明确指出指向成员的指针是 POD。
0 进行初始化,如果在函数外部,则它们是未定义的。
具有自动和动态存储持续时间的非类变量的默认初始化会生成具有不确定值的对象(静态和线程局部对象初始化为零)
引用和 const 标量对象不能默认初始化。 看下面的例子
#include <string>
struct T1 { int mem; };
struct T2
{
int mem;
T2() { } // "mem" is not in the initializer list
};
int n; // static non-class, a two-phase initialization is done:
// 1) zero initialization initializes n to zero
// 2) default initialization does nothing, leaving n being zero
int main()
{
int n; // non-class, the value is indeterminate
std::string s; // class, calls default ctor, the value is "" (empty string)
std::string a[2]; // array, default-initializes the elements, the value is {"", ""}
// int& r; // error: a reference
// const int n; // error: a const non-class
// const T1 t1; // error: const class with implicit default ctor
T1 t1; // class, calls implicit default ctor
const T2 t2; // const class, calls the user-provided default ctor
// t2.mem is default-initialized (to indeterminate value)
}
【讨论】: