在c++中,有n个同类的对象,每一个对象都拥有自己的独立的数据成员,彼此独立,互不影响。但是突然有一天,我们写程序时,产生了一个新的需求,那就是:我们希望某一个或某几个数据为这n个同类对象所共享。于是我们可以这样来解决,1:我们把需要共享的数据设计为全部变量,但是在解决问题的时候,我们带来了更大的麻烦,那就是全局变量,在定义之后的任何时间,任何地点,任何东西都可以使用它,极大的破坏了类的封装性。2:使用在一定范围内的全局变量,这也就是我们今天所讲的静态数据成员,它可以实现在n个同类对象中实现数据共享。而静态成员函数就是用来处理静态数据成员的;
静态成员有:静态数据成员和静态成员函数;
定义:静态数据成员:static 数据类型 静态成员名;对于静态成员函数,只需要直接在前面加上static即可。如:
static void functionName();
下面来看几个例子:
1:
#include<iostream>
using namespace std;
class A
{
public:
static int count ;
void show()
{
count++;
cout << count << endl;
}
};
int main()
{
A a;
a.show();
return 0;
}
结果:error LNK2001: unresolved external symbol "public: static int A::count" (?count@A@@2HA)
这是因为静态数据成员在使用之前必须进行初始化,并且还只能在类外进行初始化;
因此可以在main之前加上:int A::count = 0;
结论:静态数据成员在使用之前必须进行初始化,并且还只能在类外进行初始化;
2:
#include<iostream>
using namespace std;
class A
{
public:
static int count ;
void show()
{
cout << ++count << endl;
}
static void showS()
{
cout << ++count << endl;
}
};
int A::count = 0;
int main()
{
A a;
a.show();
a.showS();
return 0;
}
结果:编译通过,正常打印1和2;
结论:类的静态成员函数和非静态成员函数都可以使用类的静态数据成员;
3:
#include<iostream>
using namespace std;
class A
{
public:
int count ;
void show()
{
cout << ++count << endl;
}
static void showS()
{
cout << ++count << endl;
}
};
int main()
{
A a;
a.show();
a.showS();
return 0;
}
结果:illegal reference to data member 'A::count' in a static member function;
结论:类的静态成员函数不能使用类的非静态数据成员。(类的非静态成员函数可以使用类的非静态数据成员应该没有问题吧?)
4:
#include<iostream>
using namespace std;
class A
{
public:
static int count ;
void show()
{
cout << count << endl;
}
static void showS()
{
cout << count << endl;
}
};
int A::count = 0;
int main()
{
A a;
a.count = 5;
a.show();
a.showS();
A::count++;
a.show();
a.showS();
return 0;
}
结果:正常
结论:可以通过类名::静态数据成员名在类外使用静态数据成员,也可以通过对象名.静态数据成员名来使用。
现在作个总结:
1:静态数据成员在使用之前必须被初始化,并且只能在类外进行初始化;
2:静态数据成员被所有对象所共享,在所有对象之外单独开辟内存空间存储;
3:静态数据成员所占有的内存空间不随某个对象的撤销而释放;
4:静态数据成员既可以通过对象名来引用也可以通过类名来引用(静态数据成员并不是属于对象的,而是属于类的,但类的对象可以引用它);
5:如果静态数据成员被定义为私有的,则不能在类外直接引用,而必须通过公用的成员函数引用;
6:静态数据成员实现了各对象之间的数据共享,同时避免了使用全局变量破坏了封装的原则;
7:静态数据成员的作用域只限定于定义该类的作用域内;在此作用域内,可以通过类名或是域运算符“::”引用静态数据成员,而不论类对象是否存在;
8:类的静态成员函数和非静态成员函数都可以处理类的静态数据成员;
9:类的静态成员函数不能处理类的非静态数据成员;