===============================================
转载时请表明出处:
《C++学习笔记》静态数据成员
http://www.cofftech.com/thread-1403-1-1.html
欢迎大家跟帖讨论哈~~~~~
===============================================
各函数之间数据共享的一种方法是使用全局变量。但按照软件工程的观点,这不安全,应尽量少用。
如果只在同一类的多个对象之间实现数据共享,则可使用该类的静态数据成员,即由同一类的各对象共享该类的静态数据成员。这样的做法可避免使用全局变量所带来的危险。
类的静态成员分为静态数据成员和静态成员函数两种。在编译过程中,在给出类定义后,即使该类没有建立任何对象,其静态数据成员也已经存在,并被分配在数据区内。这是与非静态数据成员的一个不同点。
静态数据成员属于一个类而不属于该类的任何对象,它由该类中的所有对象所共享。静态数据成员的生命周期是整个程序,而其作用域是它被定义时所在的类的所有对象。
既然静态数据成员是一个类中所有对象所共享的,因此它不存放在栈区内各对象的各内存栈区空间中,而是存放在数据区内。同时它只有一份。这个类的任何对象都能访问它、将它更新。何以见得?且看以下各例。
先看各种成员的地址。
[例1]读取非静态数据、静态数据和主程序的地址
#include <iostream.h>
class base
{
public:
int i;
static int s;
};
int base::s = 23; // this should not be omitted,
// otherwise there will be error LNK2001:
// unresolved external symbol "public: static int base::s"
void main()
{
base bb;
cout<<"static member bb.s="<<bb.s<<endl;
cout<<"address of static member bb.s="<<&bb.s<<endl;
cout<<"address of non-static member bb.i="<<&bb.i<<endl;
cout<<"code address of main( )="<<main<<endl; //or &main
}
/* Results:
static member bb.s=23
address of static member bb.s=0x00428D64
address of non-static member bb.i=0x0012FF7C
code address of main( )=0x00401023
*/
[例2]四个对象共享一个静态数据
#include <iostream.h>
class counter
{
static int count; //用于表示已建立的对象数目
int objnum; //用于表示对象序号
public:
counter ( )
{ count++; //每建立一个对象就加一
objnum = count; //为当前对象序号赋值
}
void show( )
{ cout<<"obj"<<objnum<<" created"<<endl;
cout<<"totally "<<count<<" object(s)"<<endl;
}
};
int counter::count; //自动初始化为零
// this should not be omitted,
// otherwise there will be error LNK2001:
// unresolved external symbol "public: static int counter::count"
void main()
{
counter obj1;
obj1.show( );
counter obj2;
obj2.show( );
counter obj3;
obj3.show( );
counter obj4;
obj4.show( );
}
/* Results:
obj1 created
totally 1 object(s)
obj2 created
totally 2 object(s)
obj3 created
totally 3 object(s)
obj4 created
totally 4 object(s)
*/
[例3]以上例2也可用另一种形式表达,使用指针调用运算符new,如下:
#include <iostream.h>
class counter
{
static int count; //用于表示已建立的对象数
int objnum; //用于表示对象序号
public:
counter ( )
{ count++; //每建立一个对象就加一
objnum = count; //为当前对象序号赋值
}
void show( )
{ cout<<"obj"<<objnum<<" created"<<endl;
cout<<"totally "<<count<<" object(s)"<<endl;
}
};
int counter::count; // this should not be omitted,
// otherwise there will be error LNK2001:
// unresolved external symbol "public: static int counter::count"
void main()
{
counter *ptr1 = new counter;
ptr1->show( );
counter *ptr2 = new counter;
ptr2->show( );
delete ptr1;
delete ptr2;
}
/* Results:
obj1 created
totally 1 object(s)
obj2 created
totally 2 object(s)
*/
[例4]同一类的两个对象共享静态数据成员
#include <iostream.h>
class Myclass
{
int x, y;
static int Sum;
public:
Myclass (int a, int b);
int GetSum ( );
};
int Myclass::Sum; // Type name "int" must be used.
// Objects not created yet.
// If this datum is to be used, this statememt should not be omitted,
// or there will be fatal linking error:
// unresolved external symbol "private: static int
// Myclass::Sum"
Myclass::Myclass(int a, int b)
{
cout<<(x = a)<<";"<<(y = b)<<endl;
Sum += x+y; //Sum = Sum + x + y;
}
int Myclass::GetSum( )
{
return Sum;
}
void main()
{
Myclass obj1(1,5);
cout<<"sum="<<obj1.GetSum( )<<endl;
Myclass obj2(3,6);
cout<<"sum="<<obj2.GetSum( )<<endl;
}
/* Results:
1;5
sum=6
3;6
sum=15 */
静态数据成员的说明、定义和初始化:
从上例可以看出,在类体内说明静态数据成员后,在对它进行读、写之前,必须在类体之外进行定义,使其初始化。(如不显式地初始化为一定值,则系统自动将其初始化为零值)。