静态成员
在说明前面加上static关键字,普通成员变量每个对象有各自的一份,而静态成员变量一共就一份,为所有对象共享。如果是public,那么静态成员在没有对象生成的时候也能直接访问。
静态成员变量本质上是全局变量,哪怕一个对象都不存在,类的静态成员变量也存在
静态成员函数本质上是全局函数。
访问静态成员
1)类名::成员名 Class::PrintData();Class::Data;
2)对象.成员名 Object.PrintData();
指针->成员名 Class *ptrObject;
ptrObject->PrintData();
3)引用.成员名
Class &refObject=Object;
refObject.PrintData();
sizeof运算符不会计算静态成员变量
静态成员函数也不与任何对象绑定在一起,它们不包含this指针。作为结果,静态成员函数不能声明为const的,而且我们也不能再static函数体内使用this指针。这一限制既适用于this的显示使用,也对调用非静态成员的隐式使用有效。
在静态成员函数中,不能访问非静态成员变量,也不能调用非静态成员函数。
因为按照第一种访问方式将不知道访问的非静态成员变量是属于哪个对象的。
定义静态成员
当我们在类的外部定义静态成员时,不能重复static关键字,该关键字只出现在类内部的声明语句
.成员名
类的静态成员变量和函数中的静态变量一样,在编译的时候就分配内存了,直到程序退出才释放,并不是随着对象的删除而释放的:
类的静态成员变量为什么必须得在类外初始化?
我的理解: 由于静态变量在编译期间必须初始化,全局变量的静态或者非静态的变量都可以赋初值0。而类中的变量要用构造函数来初始化,但是在编译期间没有创造对象,所以就没有运行构造方法。故在编译期间没有给类的静态变量初始化。所以要在类外 main之前要给该静态变量初始化,不管该静态变量的作用域为private还是public,因为编译期间private没有影响。但是一旦进入运行(链接)时,就不可以调用类中的private变量。
静态成员的类内初始化
总结:
Class Account{
Public:
staticvoid f(){}
private:
static const int i = 1;
static int interestRate;
int j;
static int initRate();
};
Class Account acc;
1、static数据成员和static成员函数都是与类有关,与对象不相关,不属于类的任何一个对象。它的作用域是类(因为在类中定义),所以在访问时需要加上作用域运算符。生命周期是整个程序(因为定义的方式是static).
Account::f();
2、类的静态成员函数没有this指针,所以静态成员函数内不能直接使用类的非静态数据成员,不能调用类的非静态成员函数。不能声明为virtual
3、使用类的静态成员函数、类的静态数据成员,可以通过类作用域、类的对象、引用或指针
Account ac1;
ac1.f();
4、静态数据成员只属于类,不属于对象,在整个程序中只有一个副本。因此不能在定义对象时初始化,也就不能使用构造函数初始化。
应该在类外初始化,类外初始化时不加static,以免和一般的静态变量或对象混淆。
double Account::intersetRate = initRate();
5、当我们为静态成员提供const整数类型的类内初始值可以类内初始化。这是静态成员的类型必须是static constexpr int var = 30;
这些成员就是常量表达式,所以可以用在所有适合常量表达式的地方。
6、const变量的初始化。参见const的那篇文章