中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档 | 网通镜像
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > 综合其它
Imperfect C++ Practical Solutions for Real-Life Programming-Chapter11.Statics
作者:未知 时间:2005-07-27 23:25 出处:CSDN 责编:chinaitpower
              摘要:Imperfect C++ Practical Solutions for Real-Life Programming-Chapter11.Statics

 Matthew Wilson 

树人译

Chapter 11静态变量

Chapter 11静态变量

  静态对象不同于栈变量和堆变量,因为它们的内存是由链接器固定并分配的,而且它们的生存期(很大程度上)与进程的执行流是不相关的。静态对象分为三种类别:

1.         定义在函数作用域的局部静态变量。

2.         定义在全局名称空间或具名和匿名名称空间中的全局和名称空间级的静态变量,也就是通常所说的非局部静态变量。

3.         定义在类类型中的静态成员变量,它可以在同一类类型的多个类实例之间共享该变量。

  本章着眼于静态对象的使用中所固有的问题,而且提出了一些改进它们的方法。

  静态对象的初始化是一个二阶操作,这点是很重要的。首先,“实现”对它们所拥有的内存进行清零初始化。在标准(C++-983.6.31)中是这样阐述的:“所有具有静态存储生存期的局部变量会在其它任何初始化操作发生之前进行清零初始化操作。”事实上,由于这些变量被放置在链接单元(可执行程序或动态链接库)的.data(或.bss)段中,上述的过程通常是由操作系统进程装载机制来完成的,也就是简单地把数据复制到一个读写内存段中。在Listing11.1中,变量i1i2都被初始化为零。

Listing 11.1

extern int SomeOtherModulesFunc();

namespace StaticsAbound

{

    inline int LocalFunc()

    {

        return 10;

    }

    struct Thing

    {

        Thing()

            : i(SomeOtherModulesFunc())

        {}

        int i;

    } thing;

    int i1 = 0;

    int i2;

    int i3 = 1;

    int i4 = LocalFunc();

    int i5 = ::SomeOtherModulesFunc();

}

  如果静态对象是POD类型而且是从一个常量表达式来进行初始化的,那么编译器可能会把它们的值写入可执行程序中,而且因此而不需要任何运行时的初始化。也就是说,在编译/链接阶段i3的值可能被赋为1。此外,在能够确定动态初始化将导致一个相同的值的地方,一个作相关的优化并应用静态初始化的实现(编译器)是合法的(C++-983.6.22)。因此:编译器把i4静态初始化为10将是合法的。

  清零和常量初始化合在一起就是通常所说的静态初始化:这只是第一个阶段。所有其它的初始化被认为是动态初始化。任何在编译时不能完全确定的东西都要求动态初始化,包括POD类型到动态值的初始化,以及非局部静态类类型对象的构造:Listing11.1中的i5thing

  所有的静态初始化都是在任何的动态初始化之间进行的。而且,通常所有非局部静态对象的动态初始化动作会在main()函数执行之前进行,但标准并没有要求。如上所述(C++-98:3.6.2;3),非局部静态对象必须在“任何定义在同一翻译单元中的函数或对象的使用”之前进行初始化。实际上,上述的滞后初始化很少见,而且我所熟悉的编译器会在main()的入口之前进行初始化。[1]C++-98:3.6.1;1)是这样表述的:在一个独立的环境中,“启动阶段(start-up)包含了名称空间作用域中的具有静态存储生存期的对象的构造函数的执行,”这让人相信标准本身的期望是在main()之前完成非局部静态对象的动态初始化。

[1]大概这是为了迎合嵌入式或其它一些非一般的环境而定义的一个实现。


关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有