初始化问题

来源:互联网 发布:linux设置时间 编辑:程序博客网 时间:2024/05/22 13:08

原文链接:http://harttle.com/2015/10/05/cpp-variable-init.html

定义基本数据类型变量(单个值、数组)的同时可以指定初始值,如果未指定C++回去执行默认初始化(default-initialization)。 那么什么是”默认初始化”呢?

  • 栈中的变量(函数体中的自动变量)和堆中的变量(动态内存)会保有不确定的值;
  • 全局变量和静态变量(包括局部静态变量)会初始化为零。

C++11: If no initializer is specified for an object, the object is default-initialized; if no initialization is performed, an object with automatic or dynamic storage duration has indeterminate value. Note: Objects with static or thread storage duration are zero-initialized, see 3.6.2.

所以函数体中的变量定义是这样的规则:

int i;                    // 不确定值int i = int();            // 0int *p = new int;         // 不确定值int *p = new int();       // 0

静态和全局变量的初始化

未初始化的和初始化为零的静态/全局变量编译器是同样对待的,把它们存储在进程的BSS段(这是全零的一段内存空间)中。所以它们会被”默认初始化”为零。

关于进程的内存空间分配见进程的地址空间:TEXT,DATA,BSS,HEAP,STACK一文。

来看例子:

int g_var;int *g_pointer;static int g_static;int main(){    int l_var;    int *l_pointer;    static int l_static;    cout<<g_var<<endl<<g_pointer<<endl<<g_static<<endl;    cout<<l_var<<endl<<l_pointer<<endl<<l_static<<endl;};

输出:

0                   // 全局变量0x0                 // 全局指针  0                   // 全局静态变量32767               // 局部变量0x7fff510cfa68      // 局部指针0                   // 局部静态变量

动态内存中的变量在上述代码中没有给出,它们和局部变量(自动变量)具有相同的”默认初始化”行为。

成员变量的初始化

成员变量分为成员对象和内置类型成员,其中成员对象总是会被初始化的。而我们要做的就是在构造函数中初始化其中的内置类型成员。 还是先来看看内置类型的成员的”默认初始化”行为:

class A{public:    int v;};A g_var;int main(){    A l_var;    static A l_static;    cout<<g_var.v<<' '<<l_var.v<<' '<<l_static.v<<endl;    return 0;}

输出:

0 2407223 0

可见内置类型的成员变量的”默认初始化”行为取决于所在对象的存储类型,而存储类型对应的默认初始化规则是不变的。 所以为了避免不确定的初值,通常会在构造函数中初始化所有内置类型的成员。Effective C++: Item 4一文讨论了如何正确地在构造函数中初始化数据成员。 这里就不展开了,直接给出一个正确的初始化写法:

class A{public:    int v;    A(): v(0);};

封闭类嵌套成员的初始化

再来探讨一下当对象聚合发生时成员变量的”默认初始化”行为,同样还是只关注于基本数据类型的成员。

class A{public:    int v;};class B{public:    int v;    A a;};B g_var;int main(){    B l_var;    cout<<g_var.v<<' '<<g_var.a.v<<endl;    cout<<l_var.v<<' '<<l_var.a.v<<endl;    return 0;}

输出:

0 043224321 -1610612736

规则还是是一样的,默认初始化行为取决于它所属对象的存储类型。 封闭类中成员对象的内置类型成员变量的”默认初始化”行为取决于当前封闭类对象的存储类型,而存储类型对应的默认初始化规则仍然是不变的


0 0