关于全局、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. ubuntu1304无法启动桌面系统的问题和解决

    今天上班,从oracle官网下载个最新的virtual box,安装后重启电脑,进入桌面后竟然没有菜单栏和启动栏了(就是最上边的bar和左边的应用栏),而且所有启动的窗口都没有菜单栏,终端什么的也都没 ...

  2. HDU 1281 - 棋盘游戏 - [二分图最大匹配]

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1281 Time Limit: 2000/1000 MS (Java/Others) Mem ...

  3. SQL Fundamentals || DCL(Data Control Language) || 角色ROLES

    SQL Fundamentals || Oracle SQL语言 语句 解释 Create user Creates a user(usually performed by a DBA) Grant ...

  4. 启动了SSH服务后,一定要关闭Telnet服务

    https://baike.baidu.com/item/ssh/10407 https://baike.baidu.com/item/Telnet/810597

  5. pandas3

    转自:http://python.jobbole.com/81212/ 介绍 也许大多数人都有在Excel中使用数据透视表的经历,其实Pandas也提供了一个类似的功能,名为 pivot_table. ...

  6. kettle中源和目标表结构不一致的情况处理

    创建数据仓库的过程中,往往会遇到这样的问题,例如:源表由于业务原因新增了字段,而ETL程序中是按照之前的源表结构进行抽取的,那么如果不重新构建ETL程序,新的指标就不会流入DW,问题如下图所示 创建了 ...

  7. dedecms自增标签[field:global.autoindex/]的运用

    用bootstrap建站时用到幻灯片切换模块,里面有个active(下面代码中的data-slide-to="0"),其余的按顺序递增(1,2),如果用dedecms就可以用aut ...

  8. 帝国cms栏目别名怎样调用?栏目名称太短了

    在用帝国cms创建栏目时一般会填写栏目名称(较短)和栏目别名(为空则与栏目名相同),栏目别名可以设置长一些作为栏目标题,可是如何调用帝国cms栏目别名呢?默认的模板标题调用是<title> ...

  9. vue:Group XSwitch Actionsheet,Toast控件使用

    <template> <div> <div class="vux-demo"> <img class="logo" s ...

  10. Py中的多维数组ndarray学习【转载】

    转自:http://blog.sciencenet.cn/home.php?mod=space&uid=3031432&do=blog&id=1064033 1. NumPy中 ...