关于全局、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. Python 装饰器使用指南

    装饰器是可调用的对象,其参数是另一个函数(被装饰的函数). 1 装饰器基础知识 首先看一下这段代码 def deco(fn): print "I am %s!" % fn.__na ...

  2. 获取验证码随机字符串@return string $captcha,随机验证码文字

    <?php//验证码工具类class Captcha{//属性private $width;private $height;private $fontsize;private $pixes;pr ...

  3. CentOS 6U7分区大于2TB的磁盘以及挂载大于16TB分区磁盘的解决方案

    一.内容介绍1.问题描述1).问题一 CentOS 6.x 在格式化大于16TB的ext4分区时,会提示如下错误: mke2fs 1.41.12 (17-May-2010)mkfs.ext4: Siz ...

  4. POJ 1815 - Friendship - [拆点最大流求最小点割集][暴力枚举求升序割点] - [Dinic算法模板 - 邻接矩阵型]

    妖怪题目,做到现在:2017/8/19 - 1:41…… 不过想想还是值得的,至少邻接矩阵型的Dinic算法模板get√ 题目链接:http://poj.org/problem?id=1815 Tim ...

  5. linux:用户及文件权限管理

    学习内容来自实验楼.莫烦python.CSDN 一.Linux 用户管理 1. 查看用户 who am i 或者who mom likes who -a:打印所有能打印的  who -d :打印死掉的 ...

  6. centos7 安装ftp

    安装VSFTPD 1.首先确认系统内无VSFTPD. rpm -qa|grep vsftpd 若有的话会显示vsftpd-x.x.x.-x.xxx.x86_64 若没有的话会空返回 2.安装VSFTP ...

  7. 《深入理解Android内核设计思想》已陆续在全国各大书店及网上书店上市,感谢大家一直以来的支持~~

    <深入理解Android内核设计思想>已陆续在全国各大书店上市,电子书店也在陆续上架中(不断添加): 1. China-Pub 2. 京东 3. s=books&ie=UTF8&a ...

  8. cookie和session的使用

    http://www.cnblogs.com/linguoguo/p/5106618.html 1:在控制器中添加session和cookie @RequestMapping("/getin ...

  9. soapUI-Conditional Goto

    1.1.1  Conditional Goto 1.1.1.1 概述 - Conditional Goto Conditional Goto TestStep包含任意数量的XPath/JSONPath ...

  10. C# 开发圆角控件(窗体)

    最近在做卡片视图的程序,要求将控件做成带有圆角的效果,下面是我在网上查找的资料,经过测试,确定可以实现功能.其中方法三既适应于控件,也适应于窗体. 先上传效果图: 方法一: 增加命名空间:using  ...