随心而动,随意而行.

没有理想的人和行尸走肉又有什么区别呢.

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

 

http://blog.csdn.net/lee1054908698/article/details/7983253

1.静态成员数据的定义,与静态类型的变量的定义方式一样,要在成员数据的定义之前加关键字static。

2.静态成员数据必须有确定的值,但由于在类的定义中不能对成员数据直接进行初始化,故必须在类定义的外部对静态成员数据再声明一次,并进行初始化,此时,前面不需要加关键字static。同时为了保持静态成员数据取值的一致性,一般在类的构造函数中不给静态成员数据设置初值。对静态成员数据初始化的顺序为它们在类体外声明的顺序.

3.在同一个程序中,当一个类有多个对象时,则这些对象中的静态成员数据都共享同一个存储空间,即在定义类时,就为静态成员数据分配存储单元,以后创建该类的对象时,将不再为该静态成员数据分配存储单元,也不会对该静态成员数据初始化。

静态成员数据初始化格式:

<类型><类名> ::<静态成员数据> = <数值> ;

4.类的静态成员数据具有全局变量的某些特征,比如在程序开始运行时就为静态成员数据分配存储空间,但它只有类的作用域。即在执行main()之前,首先对静态成员数据和全局变量分配存储空间并进行初始化,当整个程序结束时才撤消静态成员数据和全局变量。

5.静态成员数据也可以分为公有的、私有的和受保护的静态成员。

对公有静态成员,即可以通过类的对象进行访问,也可以通过类名直接访问(这是静态成员数据与一般成员数据的另一个区别)。格式:

<类名>::<静态成员数据>

私有的和保护的静态成员数据则只能被该类的公有成员函数访问。

6.值得注意的是,在创建任何对象之前,类的静态成员数据已经存在并可以引.

7.静态成员数据也可以是用户自定义类型的数据。

 

1.2静态成员函数

1.定义静态成员函数时,只要在成员函数名前用关键字static修饰即可。

2.静态成员函数属于整个类,它是由该类的所有对象所共享的成员函数,它不属于某个对象。因此它不含有隐含的*this指针参数,故它不能像普通成员函数那样直接访问对象中的非静态的成员(成员函数和成员数据),即

静态成员函数只能访问所在类的静态的成员(成员函数和成员数据)、全局变量、外部函数等。(因为它们不属于任一个特定对象)。

3。静态成员函数若要访问非静态成员,则必须借助于类的对象(对象名或指向对象的函数参数)。

4.静态成员函数首先是一个成员函数,它可以定义为内联函数,也可以在类体外定义,但此时函数名前不必加关键字static.

5.可以通过所在类的对象访问静态成员函数(公有的)外,还可以通过类名直接访问,格式为:

   <类名>::<静态成员函数名>(<实参表>)

6.静态成员函数不能为const成员函数。

 

例1   静态成员数据的定义及应用

# include <iostream.h>

# include<stdlib.h>

class CCounter

{   static int count ;      //定义静态成员数据

int objnumber ;       //表示对象编号

public :

CCounter( )

{ count ++ ; objnumber=count ; }

void Show ( )

{ cout<<”obj”<<objnumber<<’/t’<<”count=”<<count<<’/n’ ;}

} ;

int CCounter::count=0 ; //A 在类定义外声明静态成员数据并初始化,如果不赋初值,

//可以不赋初值,此时系统会自动赋初值0。

void main ( )

{ CCounter obj 1;

obj1.Show( ) ;

cout<<”----------------------/n “ ;

CCounter obj2 ;

obj1.Show ( ) ;

obj2.Show( ) ;

cout<<”----------------------/n “ ;

CCounter obj3 ;

obj1.Show ( ) ;

obj2.Show ( ) ;

obj3.Show ( ) ;

}

执行结果:

obj1    count=1

----------------------

obj1    count=2

obj2    count=2

----------------------

obj1    count=3

obj2    count=3

obj3    count=3

 

得注意的是,在创建任何对象之前,类的静态成员数据已经存在并可以引用。

 

例2 分析程序输出的结果

类的静态成员数据具有全局变量的某些特征,在执行main()之前,首先对静态成员数据和全局变量分配存储空间并进行初始化,当整个程序结束时才撤消静态成员数据和全局变量,但它只有类的作用域。

得注意的是,在创建任何对象之前,类的静态成员数据已经存在并可以引用

# include <iostream.h>

class A

{    int i ;

   static int x ;

public :

   static int y ;

A ( int a , int b , int c )

{i=a , x=b , y =c ;}

void print ( )

{ cout<<”i=”<<i<<’/t’<<”x=”<<x<<’/t’<<”y=”<<y<<endl ;}

} ;

int A ::x=0 ;

int A ::y=0 ;

void main ( )

{count <<’y=”<<A ::y<<endl ; //B在创建任何对象之前,类中的静态成员数据就已经存在

A a (11,22,33) ;

a.print () ;

A b(100 ,200 ,300) ;

a.print () ;

b.print () ;

A::y=400 ;                            //C,私有静态成员数据不可以直接赋值。

b.print () ;

执行结果:

y=0

i=11    x=22    y=33

i=11    x=200   y=300

i=100   x=200   y=300

i=100   x=200   y=400

 

 

例: 静态成员数据的生存期

静态成员数据也可以是用户自定义类型的数据。

#include<iostream.h>

class A

{ int i ;

public :

A (int x ){i=x ; cout<<”x=”<<i<<”/t 调用构造函数A() / n “ ;}

~ A( ){cout<<”x=”<<i<<” / t 调用析构函数~A()/ n” ;}

} ;

class B

{ static A a ;           声明静态成员数据

   static A c ;

public :

B ( ) {cout<<”调用构造函数B()/ n ”;}

~B ( ) {cout<<”调用析构函数~B()/ n ”;}

};

A B ::a (10) ;                //C 在类体外声明静态成员数据并初始化

A B ::c (5) ;                  //D

A a1 (20) ;                     //定义用户自定义类型的全局变量并初始化

void main ( )

{ cout<<”main()函数开始!/ n “ ;

B b ;

cout<<”main()函数结束!/ n “ ;

}

执行结果:

x=10   调用构造函数A()

x=5   调用构造函数A()

x=20   调用构造函数A()

main ( )函数开始

调用构造函数B()

main ( )函数结束

调用析造函数~B()

x=20   调用析造函数~A()

x=5   调用析造函数~A()

x=10   调用析造函数~A()

 

注意:

在执行main()之前,首先对静态成员数据和全局变量分配存储空间并进行初始化,当整个程序结束时才撤消静态成员数据和全局变量。

对静态成员数据初始化的顺序为它们在类体外声明的顺序,如将C行和D行颠倒,则输出的第1行和第2行将要颠倒,最后两行也要颠倒。

 

 

例3: 静态成员函数的定义和使用

# include <iostream.h>

void num_Show( ) ;

class CComputer

{ float price ;

static float total ;

public :

static int num ;   //创建对象的个数

CComputer ( float i)

{ price = i ;total+= i ;num++ ;}

void show ( )

{cout<<”The computer price is : “<<price<<endl ;}

static void t_show( )           //静态成员函数

{ num_Show() ;

cout<<”total price is: “ <<total<<endl ;    //访问静态成员数据total

}

} ;

float CComputer::total=0 ;

int CComputer::num=0 ;

void num_Show( )        //输出类CComputer静态数据成员num

{cout<<”total number is: “<<CComputer::num<<endl ;}

void main ( )

{ CComputer ::t_show ( ) ;   //通过类名直接访问静态成员函数

CComputer c1(3500) ;

c1.show( );

c1.t_show( ) ;

CComputer c2(4500) ;

c2.show( ) ;

CComputer::t_show( ) ;        //A通过类名直接访问静态成员函数

}                           // c1.t_show( );c2.t_show( );

执行结果:

total number is: 0

total price is: 0

The computer price is : 3500

total number is: 1

total price is: 3500

The computer price is : 4500

total number is: 2

total price is: 8000

//A行通过类名访问其中的公有静态成员函数,该语句与如下任一语句等价:

c1.t_show( );

c2.t_show( );

 

例4: 在静态成员函数中通过对象访问类的非静态成员

静态成员函数可以直接调用所属类的其他静态成员,但不能直接访问非静态成员(成员函数和成员数据),若要访问非静态成员,则必须借助于类的对象。

#include<iostream.h>

class A

{ int x ;

static int y;

public:

A (int x1 ,int x2)

{ x=x1 ; y=y+x2 ;}

static void show1( ) ;

static void show2(A a) ;

};

void A::show1( )

{ cout<<”y=”<<y<<endl ; }    //直接访问静态数据

void A::show2 ( A a)       //

{cout<<”x=”<< a . x <<” /t “<<”y=”<<y<<endl ;}

//{cout<<”x=”<<x<<” /t “<<”y=”<<y<<endl ;} //B 错,不能直接访问非静态成员

int A::y=6 ;

void main( )

{ A a1(11 ,22) ;

a1.show1 ( ) ;         //通过对象名访问

A::show2 ( a1) ;     //通过类名访问

A a2(33,44) ;

A::show1( ) ;       //通过类名访问

a2.show2(a2) ;        //   C通过对象名访问

}

 

对C,可换用用a1.show2(a2) ;或A::show2(a2) ; //对show1() ;同理

 

执行结果:

y=28

x=11 y=28

y=72

x=33 y=72 。

 

例 7-6

z07p226L7-6

//program 7-6.cpp      

#include <iostream.h>

class claA

{ public:

       double x,y;

       static int num;     //公有静态数据成员 -- 供所有对象“共享”

                     //用于记录已通过构造函数生成了多少个对象。      

claA() {     

              x=0;       y=0;

              num++;       //每生成一个对象,num加1

       }

       claA(double x0, double y0) {

              x=x0;      y=y0;

              num++;

       }

       static void staFun()          //静态函数成员,输出静态数据成员num的当前值

{     cout<<"current_num="<<num<<endl;    }

};

int claA::num=0;     //必须在类外(使用类名限定)初始化静态数据成员

void main()

{      claA obj(1.2, 3.4), *p;

       cout<<"claA::num="<<claA::num<<”/t” ;

       claA::staFun();

       cout<<"obj.num="<<obj.num<”/t”;

       obj.staFun();

       claA A[3];           //说明具有3个对象的数组,将三次调用其构造函数

       cout<<"claA::num="<<claA::num<<”/t”;

       claA::staFun();    

p = new claA(5.6, 7.8);     生成动态对象*p,将调用构造函数

       cout<<"claA::num="<<claA::num<<”/t”;

       claA::staFun();

       cout<<"p->num="<<p->num<<”/t”;

       p->staFun();

}

        程序执行后,屏幕显示结果为:

claA::num=1        current_num=1

obj.num=1            current_num=1

claA::num=4        current_num=4

claA::num=5        current_num=5

p->num=5            current_num=5

 

注意:

      将claA类中的数据成员x、y以及num都说明为public公有型的,是为了在主调函数main中可以直接存取它们而使程序简单化,否则(对非公有型的数据成员),在类外存取它们时还要设立类似于getx()那样的公有成员函数。

http://hi.baidu.com/stringtop/blog/item/8124d361faf3a948ebf8f8ab.html

posted on 2014-07-14 17:29  随心而动,随意而行  阅读(575)  评论(0编辑  收藏  举报