posts - 297,  comments - 15,  trackbacks - 0

static关键字的用法

static c++中很常用的修饰符,它被用来控制变量的存储方式和可见性,下面我将从 static 修饰符的产生原因、作用谈起,全面分析static 修饰符的实质。

static 的两大作用:

一、控制存储方式:static被引入以告知编译器,将变量存储在程序的静态存储区而非栈上空间。1、引出原因:函数内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,大家知道,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题: 如果想将函数中此变量的值保存至下一次调用时,如何实现?最容易想到的方法是定义一个全局的变量,但定义为一个全局变量有许多缺点,最明显的缺点是破坏了此变量的访问范围(使得在此函数中定义的变量,不仅仅受此函数控制)。2 解决方案:因此c++ 中引入了static,用它来修饰变量,它能够指示编译器将此变量在程序的静态存储区分配空间保存,这样即实现了目的,又使得此变量的存取范围不变。

二、控制可见性与连接类型 :static还有一个作用,它会把变量的可见范围限制在编译单元中,使它成为一个内部连接,这时,它的反义词为”extern”.static作用分析总结:static总是使得变量或对象的存储形式变成静态存储,连接方式变成内部连接,对于局部变量(已经是内部连接了),它仅改变其存储方式;对于全局变量(已经是静态存储了),它仅改变其连接类型。

 

类中的static成员:
一、出现原因及作用:
1
、需要在一个类的各个对象间交互,即需要一个数据对象为整个类而非某个对象服务。

2、同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部,对外不可见。

类的static成员满足了上述的要求,因为它具有如下特征:有独立的存储区,属于整个类。
二、注意:
1
、对于静态的数据成员,连接器会保证它拥有一个单一的外部定义。静态数据成员按定义出现的先后顺序依次初始化,注意静态成员嵌套时,要保证所嵌套的成员已经初始化了。消除时的顺序是初始化的反顺序。
2
类的静态成员函数是属于整个类而非类的对象,所以它没有this指针,这就导致了它仅能访问类的静态数据和静态成员函数。

 

如下是对静态关键字的一些说明。

1静态全局变量
定义:在全局变量前,加上关键字 static 该变量就被定义成为了一个静态全局变量。
特点:
  A
、该变量在全局数据区分配内存。
  B
、初始化:如果不显式初始化,那么将被隐式初始化为0
  C
、访变量只在本源文件可见,严格的讲应该为定义之处开始到本文件结束。

 
例(摘于C++程序设计教程---钱能主编P103):
        //file1.cpp
        #include<iostream.h>
        void fn();
        extern int n;
        void main()
        {
          n=20;
          cout << n << endl;
          fn();
        }

        //file2.cpp
        #include<iostream.h>

        static int n; //
定义静态全局变量,初始化为0
        void fn()
        {
          n++;
          cout << n << endl;
        }

 
文件分别编译能通过,但连接时file1.cpp 中的变量n找不到定义,产生连接错误。

  D
文件作用域下声明的const的常量默认为static存储类型。
2
、静态局部变量
定义:在局部变量前加上static关键字时,就定义了静态局部变量。
特点:
  A
、该变量在全局数据区分配内存。
  B
、初始化:如果不显式初始化,那么将被隐式初始化为0
  C
、它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或 语句块结束时,其作用域随之结束。
3
、静态函数(注意与类的静态成员函数区别)
定义:在函数的返回类型前加上static关键字,函数即被定义成静态函数。
特点:
  A
、静态函数只能在本源文件中使用(这是与普通函数区别)
 
例(摘于C++程序设计教程---钱能主编P103):
        //file1.cpp
        void fn();
        void staticFn()

        void main()
        {

          fn();
          staticFn();
        }

        //file2.cpp
        #include<iostream.h>

        static void staticFn();
        void fn();

        void fn()
        {
          staticFn();
          cout << "this is fn() \n";
        }

        void staticFn()
        {
          cout << "this is staticFn() \n";
        }
连接时,将产生找不到函数staticFn()定义的错误。

  B
、主意事项
 
在文件作用域下声明的inline函数默认为static类型。
二、面象对象中的static关键字(主要指类中的static关键字)

1
、静态数据成员
特点:
  A
、内存分配:在程序的全局数据区分配。
  B
、初始化和定义:
   a
、静态数据成员定义时要分配空间,所以不能在类声明中定义。
   b
、为了避免在多个使用该类的源文件中,对其重复定义,所在,不能在类的头文件中定义。
   c
、静态数据成员因为程序一开始运行就必需存在,所以其初始化的最佳位置在类的内部实现。
  C
、特点
   a
、对相于 public,protected,private 关键字的影响它和普通数据成员一样,
   b
、因为其空间在全局数据区分配,属于所有本类的对象共享,所以,它不属于特定的类对象,在没产生类对象时其作用域就可见,即在没有产生类的实例时,我们就可以操作它。
  D
、访问形式
   a
类对象名.静态数据成员名
   b
类类型名:: 静态数据成员名
  E
、静态数据成员,主要用在类的所有实例都拥有的属性上。比如,对于一个存款类,帐号相对   于每个实例都是不同的,但每个实例的利息是相同的。所 以,应该把利息设为存款类的静态数据成员。这有两个好处,第一,不管定义多少个存款类对象,利息数据成员都共享分配在全局区的内存,所以节省存贮空间。第 二,一旦利息需要改变时,只要改变一次,则所有存款类对象的利息全改变过来了,因为它们实际上是共用一个东西。
2
、静态成员函数
特点:
  A
、静态成员函数与类相联系,不与类的对象相联系。
  B
、静态成员函数不能访问非静态数据成员。原因很简单,非静态数据成员属于特定的类实例。
作用:
 
主要用于对静态数据成员的操作。
调用形式:
  A
、类对象名.静态成员函数名()
  B
、类类型名:: 静态成员函数名() 

posted on 2009-03-27 10:36 chatler 阅读(246) 评论(0)  编辑 收藏 引用 所属分类: C++_BASIS

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

常用链接

留言簿(10)

随笔分类(307)

随笔档案(297)

algorithm

Books_Free_Online

C++

database

Linux

Linux shell

linux socket

misce

  • cloudward
  • 感觉这个博客还是不错,虽然做的东西和我不大相关,觉得看看还是有好处的

network

OSS

  • Google Android
  • Android is a software stack for mobile devices that includes an operating system, middleware and key applications. This early look at the Android SDK provides the tools and APIs necessary to begin developing applications on the Android platform using the Java programming language.
  • os161 file list

overall

搜索

  •  

最新评论

阅读排行榜

评论排行榜