Static类成员

  对于特定类类型的全体对象而言,访问一个全局对象有时是必要的。也许,在程序的任一点需要统计已创建的类对象的数量;或者,全局对象可能是指向类的错误处理例程的一个指针;或者,他是指向类类型对象的内存自由存储区的一个指针。

  然而,全局对象会破坏封装:对象需要支持特定类抽象的实现。如果对象是全局的,一般的用户代码就可以修改这个值。类可以定义类静态成员,而不是定义一个可普遍访问的全局对象。

  通常,非static数据成员存在于类类型的每个对象中。不像普通的数据成员,static数据成员独立于该类的任意对象而存在;每个static数据成员是与类关联的对象,并不是直接使用非static成员。

  1.使用类的static成员的好处

  (1)static成员的名字是在类的作用域中,因此可以避免与其他类的成员或全局对象名字冲突。

  (2)封装,static成员可以使私有成员,而全局对象不可以。

  (3)static成员是与特定类关联的。这种可见性可清洗地显示程序员的意图。

  2.定义static成员

  在成员声明之前加上关键字static将成员设为static。static成员遵循正常的公有/私有访问的规则。

  一个简单的表示银行账户的类。每个账户具有余额和拥有者,并且按月获得利息,但应用于每个账户的力量总是相同的。可以按下面这样的编写这个类 

View Code
 1 class Account{
 2 
 3        public:
 4 
 5       void applyint() { amout += amout * Rate; }
 6 
 7       static double rate() { return Rate; }
 8 
 9       static void rate(double);
10 
11     private:
12 
13       std::string owner;
14 
15       double amout;
16 
17       static double Rate;
18 
19       static double initRate();
20 
21 };

  这个类的每个对象都具有两个数据成员:owner和amout。对象没有与static数据成员对应的数据成员,但是,存在一个单独的Rate对象,有Account类型的每个对象共享。

  3.使用类static成员

  可以通过作用域操作符从类直接调用哪个static成员,或者是通过对象、引用或指向该类类型对象的指针间接调用。

View Code
 1 Account ac1;
 2 
 3   Account *ac2 = &ac1;
 4 
 5   double rate;
 6 
 7   rate = ac1.rate();
 8 
 9   rate = ac2->rate();
10 
11   rate = Account::rate();

  如同使用其他成员一样,类成员函数可以不用作用域操作符来引用类的static成员:

View Code
1 class Account{
2 
3   public:
4 
5     void applyint() { amout += amout * Rate; }
6 
7 }

  一、static成员函数

  Account类有两个名为rate的static成员函数,其中一个定义在类的内部。当我们在类的外部定义static成员是,不必重复制定static关键字,该关键子只出现在类定义体内部的声明处:

View Code
1 void Account::rate(double newRate)
2 
3   {
4 
5     Rate = newRate;
6 
7   }

  static成员没有this指针:static成员是类的组成部分担不是任何对象的组成部分,因此,static成员函数没有this指针。通过使用非static成员显示或隐式地引用this是一个编译错误。

  二、static数据成员

  static数据成员可以声明为任意类型。static数据成员必须在类定义体的外部定义。

  定义static数据成员的方式与定义其他类成员和变量的方式不同:向指定类型名,接着成员的完全限定名。

View Code
1 double Account:interestRate = initRate();

   这个语句定义名为Rate的static对象,他是类Account的成员,为double型。像其他成员定义一样,一旦成员名出现,static成员的定义就是在类作用域内。因此,我们可以没有限定的使用名为InitRate的static成员函数,作为Rate的初始化。注意,尽管InitRate是私有的,我们仍然可以使用该函数初始化Rate。像其任意的其他成员定义一样,Rate定义实在累得作用于中,因此可以访问该类的私有成员。

  1.特殊的整型const static成员

  类的static成员,像普通的数据成员一样,不在类的定义体重初始化。相反,static数据成员通常在定义时才初始化。一个例外是,只要初始化是一个常量的表达式,整型 const static数据成员就可以在类的定义体中进行初始化:

View Code
 1 Class Account {
 2 
 3   public:
 4 
 5     static double rate() { return Rate; }
 6     staic void rate(double);
 7   private:
 8 
 9     static const int period = 30;
10     double _tbl[period];
11 };

  2.static数据成员不是类对象的组成部分

  普通的成员都是给定类的每个对象的组成部分。static射程远独立 与任何对象而存在,不是类类型的组成部分。因为static数据成员不是任何对象的组成部分,所以他们的使用方式对于非static数据成员而言是不合法的。

  例如,static数据成员的类型可以使该成员所属的类类型。非static成员被限定声明为其自身类对象的指针或引用:

View Code
 1   class Bar {
 2 
 3   public:
 4 
 5     //////////
 6   private:
 7 
 8   static Bar mem1;
 9 
10   Bar *mem2;
11 
12   Bar mem3;
13 
14 };

  非static数据成员不能用作默认实参,因为他的值不能独立于所属的对象而使用。使用非static数据成员琢磨人实参,将无法提供对象以获取该成员的值,因此是错误都。

 

 

posted @ 2012-12-29 18:53  飞飞O(∩_∩)  阅读(407)  评论(0编辑  收藏  举报