Linux | c&cpp | Email | github | QQ群:425043908 关注本站

itarticle.cc

您现在的位置是:网站首页 -> 代码相关 文章内容

C++手稿:哪些变量会自动初始化?-itarticl.cc-IT技术类文章记录&分享

发布时间: 9年前代码相关 142人已围观返回

在C语言中的全局变量静态变量都是会自动初始化为0,中的局部变量不会初始化而拥有不可预测的值。 C++保证了所有对象与对象成员都会初始化,但其中基本数据类型的初始化还是依赖于构造函数。 本文将详细探讨C 风格的”默认初始化”行为和C++中成员变量的初始化规则.


初始化的语法

可能很多人至今不知道C++中如何正确地初始化一个变量,我们首先来解决语法的问题。 C语言中在声明时用=即可完成初始化操作。但我们偏向于使用C++风格(本文中均指面向对象程序设计风格)来初始化内置类型:

// C 风格

int i = 3;

int arr[] = {1, 2, 3};


// C++ 风格

int i(3);

int i = int(3);

int *p = new int(3);

int[] arr = new int[]{1, 2, 3};

C语言中int a;表示声明了整型a但未初始化,而C++中的对象总是会被初始化的,无论是否写了圆括号或者是否写了参数列表,例如:

int basic_var; // 未初始化:应用"默认初始化"机

CPerson person; // 初始化:以空的参数列表调用构造函


默认初始化规则

定义基本数据类型变量(单个值、数组)的同时可以指定初始值,如果未指定会默认初始化(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(); // 0

int i = new int; // 不确定

int i = 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<static<

cout<static<

};

输出:

0 // 全局变

0x0 // 全局指

0 // 全局静态变

32767 // 局部变

0x7fff510cfa68 // 局部指

0 // 局部静态变

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


成员变量的初始化

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

class A{

public:

int v;

};

A g_var;


int main(){

A l_var;

static A l_static;

cout<static.v<

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<

cout<

return 0;

}

输出:

0 0

43224321 -1610612736

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

发布时间: 9年前代码相关142人已围观返回回到顶端

很赞哦! (2)

文章评论

  • 请先说点什么
    热门评论
    141人参与,1条评论
    C++ 3年前
    [/鼓掌][/鼓掌][/鼓掌][/鼓掌]

站点信息

  • 建站时间:2016-04-01
  • 文章统计:728条
  • 文章评论:82条
  • QQ群二维码:扫描二维码,互相交流