静态数据成员

静态数据成员
2009-10-05 16:32

1 静态数据成员   

       要定义静态数据成员,只要在数据成员的定义前增加static关键字。静态数据成员不同于非静态的数据成员,一个类的静态数据成员仅创建和初始化一次,且在程序开始执行的时候创建,然后被该类的所有对象共享;而非静态的数据成员则随着对象的创建而多次创建和初始化。下面是静态数据成员定义的实例:

例题例10-18
 

class Test

{  public:   

               static int public_int;  

      private:   

               static int private_int;

};

void main()

{  

      Test::public_int = 145; // 正确 

      Test::private_int = 12; // 错误,不能访问私有的数据成员

}

从上例我们可以看到:静态数据成员的访问方式是:类名::静态数据成员名但是,不能直接访问私有的数据成员。其实,上面的程序段只是为了介绍如何访问静态数据成员,不能通过编译器的的编译和连接。

一、私有的静态数据成员   

为了说明私有的静态数据成员的使用,考虑下面的程序段:  

class Directory   

{    

public:    ...    

private:     

         // 数据成员    

        static char path[];   

};   

        数据成员path[]是一个私有的静态变量,在程序执行过程中,仅一个Directory::path[]存在,即使有多个Directory类的对象。静态的数据成员能够被类的成员函数访问,但不能在构造函数中初始化。这是因为静态数据成员在构造函数被调用之前就已经存在了。静态数据成员可以在定义时初始化,且必须在类和所有的成员函数之外,与全局变量初始化的方法一样。例如,类Directory的数据成员的定义与初始化方法如下:  

// 静态数据成员的定义与初始化  

char Directory::path [200] = "/usr/local";   

// 无参的构造函数  

Directory::Directory()   

{    ...   }   

        在类中的静态数据成员的定义,只是说明该类有这么一个数据成员,并没有为该数据成员分配内存。就象非静态数据成员是在创建对象时分配内存一样,静态数据成员是在初始化时分配内存的。所以,在定义静态的数组成员时,可以省略它的尺寸(数组元素的个数),但在初始化时,必须确定数组的尺寸。

二、公有的静态数据成员   

        数据成员也可以是公有的,不过我们很少定义公有的数据成员,因为它破坏了数据隐藏的原则。如果Directory类的成员path[]定义为公有的,则该成员可在类外的任一地方访问:  

void main()   

{    

        strcpy(Directory::path, "/usr/local/pub"); //修改path的值   

        …   

}   

path仍然必须先初始化:   

char Directory::path[200];

为什么需要静态数据成员?  

       类的静态数据成员拥有一块单独的存储区,而不管我们创建了多少个该类的对象。也就是说,静态数据成员被类的所有对象共享,它是属于类,而不是属于对象的。所有对象的静态数据成员都共享一块静态存储空间,可以节省内存,也为对象之间提供了一种互相通信的方法。静态数据成员的作用域在类内,也有public(公有)、private(私有)或者protected(保护)三种访问权限。 静态数据成员的存储空间分配   对于非静态数据成员而言,有多少个对象,就有多少个不同的内存单元,它们分布在各个对象的存储空间中。静态数据成员不同于非静态数据成员,不管有多少个对象,它们都共享相同的内存单元。所以,静态数据成员不应该属于任何一个对象,说它属于类更确切。  

我们用一个例子来说明这种存储空间的关系, 对于类:  

class C   

{    

            static int si;    

   static int sc;

   int i;

   char c;

   ……

};   

如果我们创建了类C的三个对象c1、c2和c3,那么它们的数据成员的存储关系如图10-2所示:

图示图10-2
 
静态数据成员的初始化   

静态数据成员的初始化必须在类外,例如:  

class A   

{

  public:

   static int i; //……   

};   

静态数据成员i的初始化方法为:

int A::i=1;

可见:它与全局变量的初始化的方法的不同之处在于,有类名和作用域分隔符指定i的范围。  

我们还可以定义静态的数组成员,例如:

例题例10-19
 

class Values

{

private:

 static const int size;

 static const float table[4];

 static char letters[5];

};

const int Values::size = 100;

const float Values::table[4] = {1.1, 2.2, 3.3, 4.4};

char Values::letters[5] = {'a', 'b', 'c', 'd', 'e'};

void main(){}

  本例创建了静态的成员变量size,静态的数组成员table和letters。静态的数组成员的初始化方法与数组的初始化类似,但要有类名和作用域分隔符限制。

成员常量   

我们先看下面一个实例:  

class A   

{

   const size = 100; //illegal

   int array[size]; //illegal   

};   

类A是想定义一个常量数组,但这个类的定义是错误的。因为定义类常量数据成员时,不能同时进行初始化。定义类时,只是说明类有那些数据成员,而不涉及到内存单元的分配,类数据成员存储单元的分配是在对象初始化时进行的。  我们也可以把常量数据成员定义成静态的,同静态成员变量初始化一样,静态成员常量初始化也在类外,

例如:

例题例10-20
 

class A

{

 static const int size;

 int array[size];

 public:

 // ...

};

const int A::size = 100; //definition

 

 

嵌套类和局部类中静态成员变量的使用  

可以很容易地把一个静态数据成员放在一个嵌套类中,它是非嵌套类中静态数据成员情况的扩展,只将它的范围进行另一个级别的指定就可以了。然而,在局部类(如在函数内部定义的类)中不能有静态数据成员。例如:

例题例10-21
 

// Nested class CAN have static data members:

class outer

{

 class inner

 {

  static int i; //OK

 };

};

int outer::inner::i = 100;

// Local class CANNOT have static data members:

void f()

{

 class local

 {

  static int i; //error

 };

}

void main

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值