Chinaunix首页 | 论坛 | 博客
  • 博客访问: 377437
  • 博文数量: 38
  • 博客积分: 256
  • 博客等级: 入伍新兵
  • 技术积分: 846
  • 用 户 组: 普通用户
  • 注册时间: 2012-12-14 23:21
文章分类

全部博文(38)

文章存档

2015年(1)

2014年(1)

2013年(28)

2012年(8)

我的朋友

分类: C/C++

2013-02-03 22:48:59

static关键字在C/C++中应用广泛,而且有不同的语义。这篇文章,我主要想探讨一下用static修饰变量的时候,它都有些什么语义,这些变量都有哪些特性。

1.源文件中用static定义全局变量

这个变量只能在这个文件中可见,其它任何文件中对这个变量都是不可见的。而且你不可以用extern把这个变量导出去。

 

2. 头文件中用static定义一个全局变量

这也是唯一一种能在头文件中定义全局变量的方式。

这种方式定义的变量有一种特性:为每一个包含这个头文件的源文件生成一个特定的变量,每个变量具有与NO.1中的变量具有同样的属性。

 

3. 定义一个类的static 成员变量

myclass.hxx

class MyClass {
public:
    static int   mVariable;

};

myclass.cxx

int MyClass::mVariable = 0;

 

4. 定义一个函数的static变量 (functional scope static variable)

这个static的作用域仅仅是在这个函数内。

 

以上描述了static变量的使用场合,这里主要是想要介绍一下这些static变量的初始化点。

 

在C++中,变量不仅仅要被初始化,而且需要一个构造过程。对于POD(plain old data)这类的变量,它们具有C-like的行为,也就是编译器会直接把初始化数据写入.data区域,而不需要额外的代码构造它们。但是对于那些具有自定义构造函数的类型来说,编译器必须安排一个点来调用它们的constructor(构造函数)。那么哪里可以安排代码来调用这些构造函数呢?

 

对于前三类的static变量,我们很好理解,它们都是在C++程序的初始化过程中被初始化的。对于C++应用程序,它们会在main被调用之前被初始化;对于Windows driver,它们会在driver start过程中被初始化,但是会在Entry function后(重要)。

 

对于第四类的static变量,我们需要详细的描述一下:

1. 这些变量都保有一块特定的存储空间,这块存储空间都会被置0在程序被装载之后;

2. 如果这些变量是POD类型,那么它们不需要任何额外的构造代码;(或者这类变量会被初始化成特定的值)

3. 对于那些具有特化构造函数的对象,这些构造函数会调用当这个函数第一次被调用时。但是在多线程环境中,构造函数的调用并不保证是线程安全的。(对于g++而言,经过验证,线程安全,而且是由一个spinlock保护的;对于Visual C++而言,它不是线程安全的,而且后面的函数调用根本不会进入static变量的构造函数,而是直接跳过了static变量的构造函数)

 

所以functional scope static variable是一个很tricky的东西,如果你不确定你在做什么,请小心用它。但是我相信C++下个标准会解决这个问题。

 

 

阅读(7382) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~