基本用法:在类内定义
class B
{
static int n;
}
然后在类外
int B::n = 2; //把这行注释掉,编译报错
这种初始化方式是由静态成员的公有性质决定的,它不能放在构造函数里由每一个对象来初始化,必须在类外实现
注意:
①一个类的static成员变量不仅为该类的所有对象所共有,也被该类的派生类对象所共有。
如:
类A中有一个static成员变量k。类A派生类B。
A a1,a2;
B b1,b2;
那么,static成员变量k为a1,a2所共有,a1对k的修改会影响到a2中k的值,a2对k的修改也会影响到a1中k的值。
b1与b2也同理。
同时,a1,a2,b1,b2也同理。即a1对k的修改会影响到a2,b1,b2中k的值。也就是无论是父类还是子类的对象,只要对static成员变量进行了修改,就会影响到所有父类及子类的对象。
②同一个作用域中是不可以定义两个同名变量的,否则就会重定义。
但若在A类中定义一个static变量k,在B类中也定义一个static变量k,尽管B是A的派生类,却不会造成重定义。其原因是:static变量都是有域名的,A中k的域名是A::k,B中k的域名是B::k。B的对象可以通过A::k及B::k来分别调用A、B中不同的static变量k。
唯一的区别在于,若A定义了static变量k而B没有定义,那么B的对象可以通过“.”来引用A的k。但若是B也定义了k,那么B的对象通过“.”来引用的k就是B自身定义的k。若此时的B对象想引用A中的k,可以通过A::k来引用。
static成员函数同理。
③考虑如下代码:
struct st
{
static int k;
};
class A
{
public:
static st m;
};
class B:public A
{
public:
static st m;
};
int st::k=1;//注意这里,是不可以用int A::m.k = 1;或int B::m.k= 2;的方式来初始化的。这是因为static变量谁定义,谁就负责初始化
void main()
{
Aa;
Bb;
b.m.k++;
cout<<a.m.k<<endl;
}
其输出是2。
这说明a,b虽然有各自的A::m与B::m,但是A::m与B::m却共享static变量k。
④将③中A、B类中的static关键字去掉,其他代码不变
则结果与③一致。这是因为struct中的static变量k为所有的struct对象所共有,无论struct对象是单独定义的或是在类内定义的或是有static关键字修饰,它们都共享static变量k。其正确的调用方式都应该是st::k。