静态成员
即定义出一些成员与类本身直接相关,而不是与类的各个对象保持关联。
1,声明静态成员
在成员的声明之前加上关键字static使得其与类关联在一起
class Test
{
public:
Test(int a) :a(a){}
void add()
{
b++;
}
static void show() //静态成员函数
{
cout << b << endl;;
}
private:
int a;
static int b; //静态成员
};
2,使用类的静态成员
- 使用作用域直接访问
- 用类的对象访问
- 用类的指针访问
Test x, *y=&x;
x.show(); //类对象
y->show(); //类指针
Test::show(); //作用域
3,定义静态成员
因为静态成员不属于类的任何一个对象,所以它并不是在创建类的对象时被定义的。这意味着它们并不是由类的构造函数初始化的。而且,一般来说不能在类内初始化静态成员。相反只能在外部定义和初始化每个静态成员。
4,静态成员的类内初始化
通常情况下,不能类内初始化,但是可以为静态成员提供const整数类型的类内初始值。不过要求静态成员必须是字面值常量类型的constexpr。
constexpr static double rate = 6.5; //如果不是const int类型则需要加上constexpr来声明是常量表达式
static const int vecSize = 20;
5,静态成员能用于某些场景,而普通函数不能
因为静态成员独立于任何对象。因此某些非静态数据成员可能非法的场合,静态成员却可以正常使用。
class Test1
{
private:
static Test1 a; //静态成员可以是不完全类型
Test1 *b; //指针可以是不完全类型
//Test1 c; 错误,数据成员必须是完全类型
}
静态成员函数
可以通过类名加范围解析运算符 :: 的方式访问,。
静态成员函数特点:只能访问静态成员数据、其他静态成员函数和类外部的其他函数。
因为静态成员函数也是属于类,并不是属于某一个对象,所以其中不包含 this 指针。因此不能访问非静态数据成员
静态成员函数与普通成员函数的区别:
- 静态成员函数没有 this 指针,只能访问静态成员(包括静态成员变量和静态成员函数)。
- 普通成员函数有 this 指针,可以访问类中的任意成员;而静态成员函数没有 this 指针。
#include<iostream>
using namespace std;
class Test
{
public:
Test(int a) :a(a){ b++; }
void show1()
{
cout << a << " " << b << endl;
}
static void show2()
{
//cout << a << endl; 不能访问类的非静态成员
cout << b << endl;
}
private:
int a;
static int b;
};
int Test::b = 0;
int main()
{
Test x(10);
x.show1();
Test y(20);
x.show1();
system("pause");
return 0;
}
运行结果:
10 1
10 2
a是非静态成员,所以属于对象x自己,所以当新定义y对象后,x的a值仍然不变:
b是静态成员,属于类,所以只要b变,则所有对象访问b的时候,值都会发生变化;