本地和全局variables如何默认初始化?
根据下面,我是对的?
- global_A引用初始化为null。
- global_int是0
- local_A引用为空
- local_int未初始化
- global_A.x和local_A.x都未初始化。
谢谢你的帮助。
A global_A; int global_int; class A { public : int x; } int main() { int local_int; A local_A; }
build立在安德烈的回应。
$ 3.6.2-“具有静态存储持续时间(3.7.1)的对象在进行任何其他初始化之前应被初始化(8.5)”。 在OP中,“global_A”和“global_int”具有静态存储持续时间。 “local_int”和“local_A”没有链接,因为它们是本地对象。
$ 8.5 / 5-为了初始化typesT的对象,意味着:
– 如果T是标量types(3.9),则将该对象设置为转换为T的0(零)值;
– 如果T是非联合类types,则将每个非静态数据成员和每个基类子对象初始化为零;
– 如果T是一个联合types,则该对象的第一个命名数据成员将被初始化;
– 如果T是一个数组types,每个元素都是零初始化的;
– 如果T是引用types,则不执行初始化。
$ 6.7.4 / 4-“所有具有静态存储持续时间(3.7.1)的本地对象的零初始化(8.5)在任何其他初始化发生之前执行.PODtypes(3.9)的本地对象具有初始化的静态存储持续时间在第一次进入块之前初始化常量expression式,允许实现在静态存储时间内执行其他本地对象的早期初始化,在允许实现静态初始化静态存储持续时间在命名空间范围(3.6.2),否则这样的对象在第一次控制通过它的声明时被初始化;这样的对象在初始化完成时被认为是初始化的,如果初始化通过抛出exception而退出,则初始化不完成当控件下一次进入声明时会再次尝试,如果控件在初始化时recursion地重新input声明 这个行为是不确定的。“
编辑2:
$ 8.5 / 9-“如果没有为对象指定任何初始化方法,并且对象是(可能是cv-qualified)非POD类types(或其数组),则该对象应该被默认初始化;如果对象是const 如果没有为非静态对象指定初始化方法,则对象及其子对象(如果有的话)具有不确定的初始值 ;如果对象或任何对象的子对象是合格的types,程序是不合格的。“
一般来说,在这方面你要把这些部分和8.5美元一起阅读。
在你的代码中没有引用,所以你提到“引用”的任何一点都没有意义。
在你的例子中,全局对象global_int
和global_A
都是零初始化的。 local_int
和local_A
都包含不确定的值,这意味着local_int
和local_A.x
没有被初始化。
PS当然,正如其他人已经指出,你的代码是不可编译的。 在声明class A
之前,您不能声明A
对象(并且在类定义之后缺lessa)。
基本上,每当你声明一个variables,编译器将调用它的默认构造函数,除非你另外指定。
语言级别的types(例如指针'int','float','bool'等)“默认构造函数”绝对没有任何作用,它只是在声明时留下内存(全局/静态variables是特例,请参阅chubsdad的答案更多的具体细节)。 这意味着它们几乎可以做任何事情,因为你通常不能确定先前在内存中的内容,甚至是内存的来源(除了“放置新的”操作符)。
你创build的类没有构造函数,所以编译器会为你生成一个默认构造函数,它只是调用每个成员/variables的构造函数。 如果将前一段中提供的信息合并,可以看到variables“x”将具有其默认构造函数,该函数不执行任何操作,因此不会被初始化为任何值。
正如其他人所说,你的代码或指针中没有引用,所以在这里所有的情况下,'NULL'这个词都是无效的。 NULL通常是指与其他语言级别types一样,除非为其赋值(除非是全局/静态variables),否则不会设置任何值。
只是为了完整性,如果你有参考:
引用必须在声明中初始化,否则会受到编译器错误的惩罚。 这意味着一个引用总是需要另一个引用它的值(比如说),这是由编译器保证的,所以你不能忘记它。 这也意味着引用不能是空指针。 但是他们提到的对象可能会失效。
global_A和local_A不是引用; 它们是对象并使用其默认构造函数创build。 默认的构造函数没有被指定,所以它将被生成,这将不会做什么,所以成员variables将保持未初始化。
A global_A;
这是一个instace,而不是一个指针,你的程序在进入main之前会调用构造函数。
要获得一个指向实例的指针,而不是一个实例,你必须写:
A* global_A;
global_int被初始化为0,因为所有的全局variables都被初始化为默认值。
每当程序进入通过调用其构造函数声明的函数时,variablesA local_A
将被初始化。
和以前一样,如果你想要一个指向A的指针,你必须编写A * local_A,但这次你必须自己初始化为NULL。
A *local_A = NULL;
varialle local_int
不会被初始化,因为它是一个基本types。
如果初始化local_A.x取决于A的构造函数,那么默认的构造函数将不会初始化local_A.x。 如果创buildA实例的类实例将使用其类的构造函数初始化x。
他们都需要初始化。 编译器会给你一个警告。
除非您转发声明A,否则此代码不会编译。
global_A引用初始化为null – 否,它将引用一个A对象。 global_int是0 – 这样认为,需要检查。 local_A引用为空 – 否,与global_A相同。 local_int是未初始化的 – 是的,它会得到一些垃圾值。 global_A.x和local_A.x都是未初始化的 – 是的。
你可以随时debugging,看看你自己。
好人..我更加困惑,因为我看到这里的回应。 无论如何,我做了一个testing,如下所示:
1#包括
2 using namespace std; 3 4 class A { 5 6 public : 7 A() : x(9) {}; 8 int x; 9 10 }; 11 12 A global_a; 13 int global_b; 14 15 int main() { 16 17 A local_a; 18 int local_b; 19 cout << "global_a.x = " << global_a.x << '\n'; 20 cout << "local_a.x = " << local_a.x << '\n'; 21 22 cout << "global_b = " << global_b << '\n'; 23 cout << "local_b = " << local_b << '\n'; 24 25 }
在ubuntu linux上使用我的g ++编译器的结果:
global_a.x = 9
local_a.x = 9
global_b = 0
local_b = 0
我认为local_b应该是未定义的,但默认情况下编译器初始化它。 不过local_a ..我不知道是否应该默认初始化。 从这里的testing.. local_a似乎被初始化。 不知道是否符合标准的C ++规范(例如,C ++ PRimer第四版说,默认的构造函数是用于声明一个类variables – 这是否意味着类types的variables被初始化,无论是全局的还是本地的?)。
无论如何,这是一个混乱的大地狱。 也许我应该放弃学习C ++。 Java是非常直截了当的。 地狱呀!
global_A引用初始化为null。
不,它是一个有效的对象(基于默认的构造函数构build,在代码中没有,但编译器添加了这个)
global_int是0
是
local_A引用为空
不,和全球一样
local_int未初始化
不,它初始化为0
global_A.x和local_A.x都未初始化。
没有两个都被初始化为0