性质
- 类的静态成员(static)存在于任何对象之外,对象中不包含任何与静态数据成员有关的数据。
- 静态成员函数也不与任何对象绑定在一起,它们不包括this指针,作为结果,静态成员函数不能声明成const的,而且我们也不能在static函数体内使用this指针。
声明
通过在成员的声明前加上关键字static使得其与类联系在一起,可以是public,也可以是private的,可以是常量、引用、指针、类类型等。
定义
既可以在类的内部也可以在类的外部进行定义。
- 外部定义时,不能重复static关键字,static只出现在类的内部声明语句中。
ps:
因为静态数据成员不属于类的任何一个对象,所以它们并不是在创建类的对象时被定义的,这意味着它们不是由类的构造函数初始化的。 - 一般来说,我们不能在类的内部初始化静态成员,必须在类的外部定义和初始化每个静态成员。
- 要想确保对象只定义一次最好的办法是把静态数据成员的定义和其他非内联函数的定义放在同一个文件中。
使用
- 使用作用域运算符直接访问静态成员:
double r;
r = Account::rate(); //rate为Account类里面的静态成员
- 仍然可以使用类的对象、引用或者指针来访问静态成员:
Account ac1;
Account *ac2 = &ac1;
//以下两种调用静态成员函数rate的方式等价
r = ac1.rate(); //通过Account的对象或引用调用
r = ac2 -> rate(); //通过指向Account对象的指针调用
- ps: 成员函数不用通过作用域运算符就能直接使用静态成员
使用场景
- 静态数据成员的类型可以就是它所属的类类型
class Bar {
public:
//...
private:
static Bar mem1; //正确
Bar *mem2; //正确
Bar mem3; //错误
};
非静态数据成员受到限制,只能声明成它所属类的指针和引用。
- 静态成员可以被用作默认实参
class Screen{
public:
//bkground表示一个在类中稍后定义的静态成员
Screen& clear (char = bkground);
private:
static const char bkground;
};
非静态数据成员不能作为默认实参,因为它本身的值属于对象的一部分,这么做的结果是无法真正提供一个对象以便从中获取成员的值,最终将引发错误。