当我们使用 static
关键字来把类或者结构成员定义为静态的时侯,无论之后创建多少个类的对象(实例),静态成员都只有一个副本,所有实例都共享这个副本。也就是说,静态成员已经不属于实例了,它归属于类,是一种类普遍存在的属性,而与实例无关。
注意我们不能把静态成员的初始化放置在类的定义中,静态成员变量在类中仅仅是声明,没有定义,所以要在类的外面定义,也就是给静态成员变量分配内存。在类的外部通过使用范围解析运算符 ::
来重新声明静态变量从而对它进行初始化,如下:
#include <iostream>class Entity
{
public:static int x, y; //声明static void Print(){std::cout << x << "," << y << std::endl;}
};int Entity::x; //定义
int Entity::y; //定义int main()
{Entity::x = 1;Entity::y = 3;Entity::Print();Entity::x = 5;Entity::y = 8;Entity::Print();std::cin.get();
}
可以看到,静态成员在类当中只是声明,而定义在外面,后面的赋值也是直接赋值,甚至不需要创建任何实例,静态成员是脱离于实例的。
而静态成员函数只能访问静态成员数据、其他静态成员函数和类外部的其他函数。如以下代码:
#include <iostream>class Entity
{
public:int x, y;static void Print(){std::cout << x << "," << y << std::endl;}
};int main()
{Entity e1;e1.x = 1;e1.y = 3;Entity::Print();std::cin.get();
}
是不会通过的,因为它相当于以下可运行代码,但是把Print(Entity e)
改为Print()
:
#include <iostream>class Entity
{
public:int x, y;
};static void Print(Entity e)
{std::cout << e.x << "," << e.y << std::endl;
}int main()
{Entity e1;e1.x = 1;e1.y = 3;Print(e1);std::cin.get();
}
也就是说,类的静态成员函数同样是与某个特定实例无关的,它归属于类。所以我们无法向它传入某个实例的成员(配不上),必须得是静态成员数据才能作为它的参数。