当前位置:   article > 正文

C++中static变量的初始化_c++ 静态成员变量初始化

c++ 静态成员变量初始化

一、初始化类型(静态&动态)

1. 静态初始化(static initialization

指的是用常量来对静态变量进行初始化。对于静态初始化的变量(请注意:包括在函数中采用静态初始化的静态变量),是在程序编译时完成的初始化编译时初始化。通常用于内置类型,常量和全局静态变量

静态初始化包括zero initialization和const initialization。

zero initialization

zero initialization的变量(未初始化的静态变量和初始化为0的静态变量)保存在.bss段,不占用rom空间(就是不占用内核镜像的空间,但是在内核加载到内存时,会保留相应的空间。)。

const initialization

const initialization的变量(已经初始化为非0的静态变量)保存在.data段

  1. // 静态初始化 - 编译时初始化
  2. // zero initialization
  3. int globalVar1; // 初始化为0,存储在.bss段
  4. const int constVar = 42; // 初始化为42,存储在.data段
  5. void foo() {
  6. static int localVar = 10; // 局部静态变量,初始化为10,存储在.bss段
  7. }
  8. int main() {
  9. foo();
  10. return 0;
  11. }
 编译时初始化
  • 在源代码被编译过程中,编译期会加入代码逻辑,以完成确定的内存分配和变量的初始化。分配内存,并非实际分配内存,而是写入其内存分配大小信息。
  • 在编译期初始化,那么在实际运行期都是确定的结构和逻辑,将带来更高的性能,因为编译器完成了一定的工作。

2. 动态初始化(dynamic initialization)

指的是需要调用函数才能完成的初始化。比如说:int a = foo(),或者是复杂类型(类)的初始化(需要调用构造函数)等。

对于这种全局静态变量、类的静态成员变量,是在main()函数执行前加载阶段时调用相应的代码进行初始化的加载时初始化)。(不是在编译期初始化!因为编译阶段还无法调用类的构造函数!同时,在加载期,是线程安全的。例如,饿汉方式的单例类)

  1. // 动态初始化 - 加载时初始化
  2. class MyClass {
  3. public:
  4. MyClass() {
  5. // 构造函数
  6. // 可以进行动态初始化
  7. }
  8. };
  9. MyClass globalObj; // 全局静态变量,加载时初始化
  10. int main() {
  11. return 0;
  12. }

仅对于局部静态变量,是在函数执行至此初始化语句时才开始执行的初始化运行时初始化),在第一次被调用时初始化,并且只初始化一次

  1. // 动态初始化 - 运行时初始化
  2. class MyDynamicClass {
  3. public:
  4. MyDynamicClass() {
  5. // 构造函数
  6. // 动态初始化
  7. }
  8. };
  9. void dynamicInitialization() {
  10. static MyDynamicClass dynamicObj; // 局部静态变量,运行时初始化
  11. }
  12. int main() {
  13. dynamicInitialization();
  14. return 0;
  15. }


二、static变量不同种类及对应的初始化

1. 全局static变量

· 如果采用静态初始化,是在编译时完成的初始化,即是在main()函数执行前由运行时调用相应的代码进行初始化的。

  1. #include <iostream>
  2. int globalStaticVar1 = 42; // 静态初始化,在编译时完成
  3. void foo() {
  4. static int localStaticVar = 10; // 静态初始化,在编译时完成
  5. }
  6. int main() {
  7. std::cout << "globalStaticVar1: " << globalStaticVar1 << std::endl;
  8. foo();
  9. return 0;
  10. }

· 如果采用动态初始化,是由加载时调用的,会在main()函数执行前由运行时调用相应的代码进行初始化的。

  1. #include <iostream>
  2. int globalStaticVar2; // 动态初始化,在加载时完成
  3. void initializeGlobalStaticVar2() {
  4. globalStaticVar2 = 100; // 初始化发生在加载时
  5. }
  6. int main() {
  7. initializeGlobalStaticVar2();
  8. std::cout << "globalStaticVar2: " << globalStaticVar2 << std::endl;
  9. return 0;
  10. }

2. 局部static变量

· 如果采用静态初始化,是在加载时完成的初始化,会在main()函数执行前由运行时调用相应的代码进行初始化的;

  1. #include <iostream>
  2. void foo() {
  3. static int localStaticVar1 = 20; // 静态初始化,在加载时完成
  4. std::cout << "localStaticVar1: " << localStaticVar1 << std::endl;
  5. }
  6. int main() {
  7. foo();
  8. return 0;
  9. }

· 如果采用动态初始化,是在运行时完成的初始化, 是函数执行至此语句完成初始化的;

  1. #include <iostream>
  2. void initializeLocalStaticVar() {
  3. static int localStaticVar2; // 动态初始化,在运行时完成
  4. localStaticVar2 = 30; // 初始化发生在运行时
  5. std::cout << "localStaticVar2: " << localStaticVar2 << std::endl;
  6. }
  7. int main() {
  8. initializeLocalStaticVar();
  9. return 0;
  10. }

3. 类的static成员变量

· 如果采用静态初始化,是在加载时完成的初始化,即是在main()函数执行前由运行时调用相应的代码进行初始化的。

  1. #include <iostream>
  2. class MyClass {
  3. public:
  4. static int staticMemberVar; // 静态初始化,在加载时完成
  5. };
  6. int MyClass::staticMemberVar = 50; // 初始化发生在加载时
  7. int main() {
  8. std::cout << "MyClass::staticMemberVar: " << MyClass::staticMemberVar << std::endl;
  9. return 0;
  10. }

· 如果采用动态初始化,也是在加载时调用的,会在main()函数执行前由运行时调用相应的代码进行初始化的。

  1. #include <iostream>
  2. class MyClass {
  3. public:
  4. static int staticMemberVar; // 动态初始化,在加载时完成
  5. };
  6. int MyClass::staticMemberVar;
  7. void initializeStaticMemberVar() {
  8. MyClass::staticMemberVar = 60; // 初始化发生在加载时
  9. std::cout << "MyClass::staticMemberVar: " << MyClass::staticMemberVar << std::endl;
  10. }
  11. int main() {
  12. initializeStaticMemberVar();
  13. return 0;
  14. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/35001
推荐阅读
相关标签
  

闽ICP备14008679号