C++:全局变量和static变量初始化
Posted imreW
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++:全局变量和static变量初始化相关的知识,希望对你有一定的参考价值。
(一)全局变量
全局变量、文件域中的静态变量、类中的成员静态变量在main函数执行前初始化;
局部变量中的静态变量在第一次调用时初始化。
C++保证,全局变量在main函数第一次使用它之前,就把它初始化好。(可以直接理解成在main函数执行前就初始化好)但这个初始化可细分为:编译时初始化和运行时初始化,即static initialization和dynamic initialization。
1.static initialization
静态初始化,是针对于那些简单的、c++内部定义的数据结构,如int,double,bool及数组结构的初始化,又可分为zero和const两种方式。
对于zero初始化,也就是我们没指定初值,编译器分配0值给它,编译时编译器将其分配在bss段,不占用rom空间;
BSS段通常是指用来存放程序中未初始化的全局变量和静态变量的一块内存区域。特点是可读写的,在程序执行之前BSS段会自动清0,所以,未初始的全局变量在程序执行之前已经成0了。
而const初始化,也就是我们指定了初值,编译器将其分配在data段,占用rom空间。
数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。
2.dynamic initialization
这种初始化针对的是需要调用构造函数才能完成的初始化。这种初始化会在main函数执行前,在运行时由运行时库调用相应的代码进行初始化。
另外,静态初始化先于动态初始化。因为静态初始化发生在编译时期,直接写进bss段和data段,在程序执行时直接加载;
而动态初始化则是在运行时期,由运行时库调用相应构造函数进行初始化,同样要写进bss段或data段。
(二)类的静态成员
C++规定,const的静态成员可以直接在类内进行初始化,而非const的静态成员需要在类外声明以初始化。
使用过类中的静态成员变量的伙伴都发现了,在类中定义的静态成员变量,还必须要在类外定义下才可以使用,否则会编译报错。
那么为什么会出现这种情况呢?
静态成员变量不属于任何一个对象,对象的数据中不应该包含静态成员的数据。所以在定义类的时候不会给静态变量分配内存只是声明,因此就要在其他地方分配即定义。
定义与声明的区别:
声明:只是向程序表面变量的类型和名字。
定义:为变量分配内存,也可以顺便初始化。程序中变量有且只有一个定义(更能说明为什么要在类外再定义下类的静态成员变量了)。
C++面向对象-static、const
参考技术A被static修饰的成员变量、函数,可以通过对象,对象指针,类访问,静态成员变量在数据段,类似于全局变量,整个程序运行中只有一份内存。但是静态成员变量可以通过类设定它的访问权限,比如public、protected、private来修饰达到局部共享的目的。 static成员变量必须初始化,而且必须在类外面初始化,初始化时不能带static 。
静态成员由于是存在全局区,不会跟着对象销毁而释放,下面我们结合static函数来看下。
静态成员函数内部不能使用this指针 ,this指针只能在非静态成员函数内部使用, 虚函数也不能是静态成员函数 ,虚函数只能是非静态成员函数, 静态成员函数内部不能访问非静态成员变量、函数,只能访问静态成员变量、函数, 非静态成员函数内部可以访问静态成员变量、函数,构造函数、析构函不能是静态成员函数,当静态成员函数声明与实现分离时,实现部分不能带static。
在开发中我们经常有这种需求,在运行程序中,我们对象保持一份,不允许重复创建,而且外部拿到的对象保证只有一份,这时用static成员和static成员函数构成的单例模式非常实用。下面我们来看看这个经典的单例模式的应用:
我这里得到的是p1和p2、p3、p4相等,p1指向的对象被销毁了一次,相等属于巧合。而p2、p3、p4相等是因为他们指向同一个对象。
类里面的const成员: 被const成员修饰的成员变量,非静态成员函数 ,const成员变量: 必须初始化,在类内部初始化,可以在申明的时候初始化赋值,非static的const成员变量还可以在初始化列表中初始化。 const成员函数:const放在函数参数列表后面,函数的声明和实现都必须带const, 内部不能修饰非static成员变量,其内部只能调用const函数和static成员函数,非const成员函数可以调用const成员函数,const成员函数和非const成员函数可以构成重载,非const成员函数优先调用非const成员函数,而const成员函数只能调用const或者static成员函数。 示例如下:
引用类型成员变量必须初始化,在声明的时候直接初始化,或者在初始化列表的时候初始化。
以上是关于C++:全局变量和static变量初始化的主要内容,如果未能解决你的问题,请参考以下文章