转:C语言中的static变量和C++静态数据成员(static member)

转自:C语言中的static变量和C++静态数据成员(static member)

C语言中static的变量:
1).static局部变量
        a、静态局部变量在函数内定义,生存期为整个程序运行期间,但作用域与自动变量相同,只能在定义该变量的函数内使用。退出该函数后, 尽管该变量还继续存在,但不能使用它。
        b、对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。
2).static全局变量
        全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。但是他们的作用域,非静态全局变量的作用域是整个源程序(多个源文件可以共同使用); 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件(.h或.cpp)内有效, 在同一源程序的其它源文件中不能使用它(注意,这一点和C++是不同的)。

关于C语言static变量的理解:

A、若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;

B、若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;

C、静态变量和全局变量放在程序的全局数据区,而不是在堆栈中分配,所以不可能导致堆栈溢出;

D、设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题(线程不安全);

C++中静态数据成员的特点有::

          1、静态数据成员仅仅在初始化时不受访问权限的约束;

2、静态数据成员最好不要在.h文件中进行定义(初始化),而是放在.cpp文件中定义(初始化);

3、静态数据成员被类的所有对象所共享,包括类的派生类的所有对象;——即派生类和基类共享一个静态成员。

4、静态数据成员的类型可是所属类自己,即在一个类中可以声明该类自己的类型的静态成员对象,但是,不可以定义普通的成员对象,(指针可以)

5、在const成员函数中,可以修改static成员变量的值。普通成员变量的值,是不能修改的。

6、static成员函数只能访问static成员,不能访问非static成员,并且static成员函数不能定义为virtual、const、volatile 函数。

详细分析如下:

     类体中的数据成员的声明前加上static关键字,该数据成员就成为了该类的静态数据成员。

        和其他数据成员一样,静态数据成员也遵守public/protected/private访问规则。注意::仅仅是初始化时不遵守public/protected/private的规则。

        即:如果是private和protected的静态成员,只能通过public的静态成员函数进行调用,而不能通过类名直接访问了。

1、静态数据成员的定义(初始化)不能在头文件中。 
     静态数据成员实际上是类域中的全局变量。所以,静态数据成员的定义(初始化)不应该被放在头文件中。 
    其定义方式与全局变量相同。举例如下: 
xxx.h文件 
class base


       private: 
               static const int _i;           //声明,标准c++支持有序类型在类体中初始化,但vc6不支持。 
};

xxx.cpp文件 
const int base::_i=10;                 
//仅仅在定义(初始化)时不受private和protected访问限制.

注:不要试图在头文件中定义(初始化)静态数据成员。在大多数的情况下,这样做会引起重复定义这样的错误。即使加上#ifndef #define #endif或者#pragma once也不行。

2、静态数据成员   被 类 的所有对象所共享,包括该类派生类的对象。即派生类对象与基类对象共享基类的静态数据成员。举例如下: 
class base


       public : 
               static int _num;         //声明 
}; 
int base::_num=0;                   //静态数据成员的真正定义

class derived:public base


};

main() 

      base a; 
      derived b; 
      a._num++; 
      cout<<"base class static data number _num is"<<a._num<<endl; 
      b._num++; 
      cout<<"derived class static data number _num is"<<b._num<<endl; 

// 结果为1,2;可见派生类与基类共用一个静态数据成员。

3、静态数据成员的类型可以是所属类的类型,而普通数据成员则不可以。普通数据成员的只能声明为所属类类型的 指针或引用。举例如下:

class base{ 
        public : 
               static base _object1;                       //正确,静态数据成员 
               base _object2;                                  //错误 
               base *pObject;                                  //正确,指针 
               base &mObject;                               //正确,引用 (引用需要在构造函数的参数初始化列表中初始化,如下:)
};

这个类要能创建对象,需要定义带有参数初始化列表的构造函数,如下:

class base{ 
       public : 
             static base _object1; //正确,静态数据成员 
             base *pObject;            //正确,指针 
             base &mObject;         //正确,引用

             base():mObject(*this){}                
};

4、静态数据成员的值在const成员函数中可以被合法的改变,而不破那个数据成员的值,不能在const成员函数中改变。

#include <iostream>
using namespace std;

class Student
{
 private:
  static int a;
  int b;
 public:
  void change() const;
  void setB(int b);
  int getB();
  static int getA();
};

void Student::change() const
{
          a++;         
 //这个可以,因为a是static成员变量。
          b++;          
//不可以,因为b是普通成员变量(如果b不是成员变量(是全局变量,普通参数,函数内部定义的临时变量)也可以别修改),且是const函数
}
int Student::getA()
{
         return a;
}
void Student::setB(int b)
{
         this->b = b;
}
int Student::getB()
{
         return b;
}
int Student::a = 5;

int main(int argc,char *argv[])
{
       Student stu;
       stu.setB(10);
       stu.change();
       cout<<Student::getA()<<endl; 
       cout<<stu.getB()<<endl;
       return 0;
}

即:成员函数的const约束,只起作用于类的普通成员变量,对于全局变量,成员函数参数,成员函数内部的临时变量起不到作用。

时间: 2024-10-11 07:15:22

转:C语言中的static变量和C++静态数据成员(static member)的相关文章

C语言中的extern变量

C语言中的extern变量 extern变量是全局变量的扩充. 全局(global)变量 在任何一个函数之外声明的变量就是全局变量,全局变量可以被声明所在文件中的任何一个函数调用.全局变量只可以被定义一次. int globalVar globalVar定义为全局变量时,默认初值为0,并且系统为之分配相应的内存.现在,定义该变量的文件中的任意一个函数可以调用它. extern变量 假如你想要调用另外一个文件中的全局变量,如果你再声明一个同名的全局变量,那么编译器会因为重名报错,这个时候就要使用e

在C语言中,double long unsigned int char 类型数据所占字节数

在C语言中,double  long  unsigned  int  char  类型数据所占字节数和机器字长及编译器有关系:所以,int,long int,short int的宽度都可能随编译器而异.但有下面几条原则(ANSI/ISO制订的): 1 sizeof(short int)<=sizeof(int) 2 sizeof(int)<=sizeof(long int) 3 short int至少应为16位(2字节) 4 long int至少应为32位. unsigned 是无符号的意思.

static静态数据成员

类体中的数据成员的声明前加上static关键字,该数据成员就成为了该类的静态数据成员.和其他数据成员一样,静态数据成员也遵守public/protected/private访问规则.同时,静态数据成员还具有以下特点: 1.C++静态数据成员的定义. 静态数据成员实际上是类域中的全局变量.所以,静态数据成员的定义(初始化)不应该被放在头文件中. 其定义方式与全局变量相同.举例如下: xxx.h文件 1. class base{      2. private:      3. static con

Java static 变量,方法 静态初始化化块

static修饰的变量和方法属于类,在类加载时在内存中分配空间: 调用时可以直接通过类名调用,当通过创建对象改变的是静态变量时,那么该静态变量就改变了: 静态方法中不能直接访问非静态的成员变量和方法,可以通过创建对象访问:反之,非静态的成员变量可以访问静态的变量和方法: 可以通过构造器,初始化块和静态初始化块来给成员变量赋值:相比于构造器和初始化块在没创建一个对象时执行一次,并且初始化块在构造器之前执行:静态代码块只执行一次:

Java语言中的volatile变量

Java中的两种内置同步机制: synchronized 和 volatile 变量, volatile修饰的变量, 在使用时会强制检查最新值. 有synchronized的值可见性, 但是没有其操作原子性. 因为其轻量的原因, 在一些考虑性能的地方, 可以使用volatile, 但是使用时要非常小心. 常用的场景是: 少写多读, 并且写入口唯一的情况. http://www.ibm.com/developerworks/java/library/j-jtp06197/index.html Us

[转] C语言中static变量详解

转自:http://blog.chinaunix.net/uid-26822028-id-3191967.html 作者:gecedu Static翻译出来是"静态""静止"的意思,在C语言中的意思其实和它的本意差不多,表示"静态"或者"全局"的意思,用来修饰变量和函数.经static修饰过后的变量或者函数的作用域或者存储域会发生变化,而由static修饰的变量在初始值方面也会表现出static关键字的优势.想知道经stati

C语言中static变量详解

Static翻译出来是“静态”“静止”的意思,在C语言中的意思其实和它的本意差不多,表示“静态”或者“全局”的意思,用来修饰变量和函数.经static修饰过后的变量或者函数的作用域或者存储域会发生变化,而由static修饰的变量在初始值方面也会表现出static关键字的优势.想知道经static修饰过后的变量或者函数的作用域或者存储域发生了什么变化吗,发生变化的原因是什么吗?请大家继续往下看! 一.c程序的内存分布 既然static是用来修饰变量和函数的,而变量和函数又是组成c程序必不可少的,C

C语言中static关键字的作用

static的作用(精辟分析) 在C语言中,static的字面意思很容易把我们导入歧途,其实它的作用有三条. (1)先来介绍它的第一条也是最重要的一条:隐藏. 当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性.为理解这句话,我举例来说明.我们要同时编译两个源文件,一个是a.c,另一个是main.c. 下面是a.c的内容 char a = 'A'; // global variable void msg()  {     printf("Hello\n"

如果你去面试-C语言中static的作用

C 语言中 static的作用有三条 1,隐藏 当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性. 如果加了static,就会对其它源文件隐藏. 利用这一特性可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突.Static可以用作函数和变量的前缀,对于函数来讲,static的作用仅限于隐藏,而对于变量,static还有下面两个作用. 2,static的第二个作用是保持变量内容的持久. 存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一