关于全局、static对象/变量的初始化问题
1. 全局变量、static变量的初始化时机:main()函数执行之前(或者说main中第一个用户语句执行之前)。
2. 初始化顺序
1)全局对象、外部static对象
    a)同一编译单元(同一源文件)中,按照对象/变量的定义顺序初始化。
    b)不同编译单元,C++标准未保证初始化先后顺序,只保证都在main()之前初始化完成。
2)函数内部local static变量,在该函数调用过程中第一次遇到该static变量时初始化。
 
     基于以上观点,大师们建议少用全局变量,全局变量之间要消除依赖关系——特别是初始化依赖关系!
     全局变量的使用可以参考 Scott Meyers 在《More Effective C++》中M34所说的,模拟Singleton模式,通过函数内部的local static变量来代替全局变量。
     写个示例程序验证下这些变量的初始化,中间的注释部分就作为上面结论的一些补充吧。

class CA
{
public:
     class CInner
     {
     public:
          CInner()
          {
               cout << "constructor of inner class CInner." << endl << endl;
          }
     };
public:
     CA()
     {
          cout << "Constructor of CA." << endl;
          cout << " m_i1 = "  << m_i1
                  << ", m_i2 = " << m_i2
                  << ", m_i3 = " << m_i3
                  << ", m_i4 = " << m_i4 << endl << endl;
     }
     static void Func1()
     {
          cout << " In function Func1()." << endl;
          static CInner myInner1;
     }
     static void Func2()
     {
          cout << " In function Func2(), m_i1 = " << m_i1 << endl;
          if(m_i1 < 10)
          {
               cout << "m_i1 < 10 and Constructor of CInner won't be called!" << endl << endl;
               return;
          }
          static CInner myInner2;
     }
public:
     static int m_i1;
     static int m_i2;
     static const int m_i3;
     static int m_i4;
};
/* 不同模块的全局、static变量/对象初始化顺序不确定;
 * 同一个编译模块按定义顺序初始化。
 * 但有一点相同,就是它们均在编译期已分配好内存。
 * 对于诸如基本数据类型,编译期能确定其值的,编译器就直接将值写入分配的空间,如“CA::m_i1=3"。
 * 对于编译期不能确定值的,要等到运行时main函数之前初始化,如theCA、CA::m_i2。
 * 但若static的初始化表达式均为const或字面常量等确定的值,则亦能在编译期确定值,如m_i4。
 */
int CA::m_i1 = 1;
CA theCA;
const int  CA::m_i3 = 3;
int CA::m_i2 = CA::m_i1 + 1;
int CA::m_i4 = CA::m_i3 + 1;
int main(int argc, _TCHAR* argv[])
{
     CA::Func1();
     CA::Func2();
     cout << "After CA::m_i1 increased by 11 :" << endl;
     CA::m_i1 += 11;
     CA::Func2();
     return 0;
}

以上程序运行结果为:
Constructor of CA.
 m_i1 = 1, m_i2 = 0, m_i3 = 3, m_i4 = 4
 In function Func1().
constructor of inner class CInner
 In function Func2(), m_i1 = 1
m_i1 < 10 and Constructor of CInner won't be called!
After CA::m_i1 increased by 11 :
 In function Func2(), m_i1 = 12
constructor of inner class CInner.

C/C++之全局、static对象/变量的初始化问题的更多相关文章

  1. static, const 和 static const 变量的初始化问题

    const 常量的在超出其作用域的时候会被释放,但是 static 静态变量在其作用域之外并没有释放,只是不能访问. static 修饰的是静态变量,静态函数.对于类来说,静态成员和静态函数是属于整个 ...

  2. static对象

    1.static对象包括: global对象 namespace作用域下的对象 在class,function,file作用域内的static对象 2.在方法内的static对象成为 local st ...

  3. static 成员变量、static 成员函数、类/对象的大小

    一.static 成员变量 对于特定类型的全体对象而言,有时候可能需要访问一个全局的变量.比如说统计某种类型对象已创建的数量. 如果我们用全局变量会破坏数据的封装,一般的用户代码都可以修改这个全局变量 ...

  4. iOS中block 静态全局局部变量block变量,以及对象,详解!

    //最近总是犯迷糊,关于block对外部变量的引用,今天有时间就写了一下,加深自己的理解,巩固基础知识 1 #import <Foundation/Foundation.h> ; int ...

  5. -1-2 java 面向对象基本概念 封装继承多态 变量 this super static 静态变量 匿名对象 值传递 初始化过程 代码块 final关键字 抽象类 接口 区别 多态 包 访问权限 内部类 匿名内部类 == 与 equal

    java是纯粹的面向对象的语言 也就是万事万物皆是对象 程序是对象的集合,他们通过发送消息来相互通信 每个对象都有自己的由其他的对象所构建的存储,也就是对象可以包含对象 每个对象都有它的类型  也就是 ...

  6. c++学习笔记之类和对象(三、static静态成员变量和静态成员函数)

    一.static静态成员变量 对象的内存中包含了成员变量,不同的对象占用不同的内存,这使得不同对象的成员变量相互独立,它们的值不受其他对象的影响.是有时候我们希望在多个对象之间共享数据,对象 a 改变 ...

  7. jvm源码解读--09 创建oop对象,将static静态变量放置在oop的96 offset处 第二篇

    先打断点systemDictionary.cpp 1915行 Universe::fixup_mirrors(CHECK); 进入 void Universe::fixup_mirrors(TRAPS ...

  8. jvm源码解读--08 创建oop对象,将static静态变量放置在oop的96 offset处

    之前分析的已经加载的.Class文件中都没有Static 静态变量,所以也就没这部分的解析,自己也是不懂hotspot 将静态变量放哪里去了,追踪源码之后,看清楚了整个套路,总体上来说,可以举例来说对 ...

  9. android 尽量不要使用static静态变量

    使用静态static静态变量潜在性问题: 1.占用内存,并且内存一般不会释放: 2.在系统不够内存情况下会自动回收静态内存,这样就会引起访问全局静态错误. 3.不能将activity作为static静 ...

随机推荐

  1. React 属性和状态的一些总结

    一.属性 1.第一种使用方法:键值对 <ClaaNameA name = “Tom” /> <ClaaNameA name = {Tom} /> <ClaaNameA n ...

  2. PPTP不使用远程网关访问公网设置

    使用PPTP拨号的时候默认使用PPTP远程网关访问公网,通过以下设置可以禁止远程网关访问公网 1,右下角选择网络图标右键-属性 2,选择网络IPv4属性,选择属性 3,点击高级选项 4,在远程网络上使 ...

  3. 牛客网多校赛第9场 E-Music Game【概率期望】【逆元】

    链接:https://www.nowcoder.com/acm/contest/147/E 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言524 ...

  4. 使用IntelliJ IDEA进行Python远程调试的需求(未完)

    使用IntelliJ IDEA进行Python远程调试的需求(未完) 在研究深度学习Machlearning时,有时候需要借助ubuntu搭建的tensorflow环境,另外也有越来越多的运算程序只能 ...

  5. AIX 7命令行weblogic建域流水

    $ ./config.shUnable to instantiate GUI, defaulting to console mode. <------------------- Fusion M ...

  6. flask之表单验证 2018.12.23

    #flask的消息闪现依赖于flash库,用户发送的请求方式存储在request模块中 #跳转依赖于redirect模块,还可以通过url_for方法来进行方法上的寻址 from flask impo ...

  7. QtCore是Qt的精髓(包括五大模块:元对象系统,属性系统,对象模型,对象树,信号槽)

    作者:小豆君的干货铺链接:https://www.zhihu.com/question/27040542/answer/218384474来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业 ...

  8. lua 获取指定目录下指定后缀文件名

    lfs库是很好的选择,可惜不会编译,无奈只能自己写个简单的lua库.代码如下: #include <io.h> #include <stdio.h> #include &quo ...

  9. 前端 HTML的规范

    1.编写HTML规范 1)所有标记元素都要正确的嵌套,不能交叉嵌套.正确写法举例:<h1><font></font></h1> (2)HTML标签通常是 ...

  10. iframs刷新的两种方法

    <iframe src="a1.html" id="iframe1Id" name="iframe1Name" width=" ...