静态成员包括静态数据成员和静态函数成员两部分
注意:类体中的成员的声明前加上static关键字,该成员就成为了该类的静态成员。和其他成员一样,静态成员也遵守public/protected/private访问规则。
一、静态数据成员
为什么要引入静态数据成员:主要原因是为了取代全局变量。
什么时候使用静态数据成员:主要用途是定义类的各个对象公有的数据,如统计总数,平均数
语法:
定义:static + 普通数据成员定义
初始化位置:必须在类外初始化,主函数前,而不能在类中进行初始化
初始化:类型 类名::变量 = 值;------注意这时,前面不能加static
使用:
类外使用:
访问规则:public
使用方式:类对象名.静态数据成员名 或 类类型名::静态数据成员名
类中使用:
访问规则:public/protected/private(可以是任意方式定义)
使用方式:直接使用静态成员名
举例:
静态成员的定义:static int x;
静态成员初始化:int A::x=1;
性质:
1、针对类而言,只有一个静态数据存储空间 且 存储空间不由构造函数分配
2、静态数据成员在编译时创建并初始化,在所有类的任何对象被建立前就存在。
3、静态数据成员被类的所有对象所共享,包括该类派生类的对象。即派生类对象与基类对象共享基类的静态数据成员。
举例:
#include<iostream>
using namespace std;
class A
{
protected:
static int num;
public:
void show()
{
cout<<"num:"<<num<<endl;
}
};
class B:public A
{
public:
B()
{
num++;
}
void show()
{
cout<<"num:"<<num<<endl;
}
};
int A::num=0;//静态数据成员的真正定义---写成 int B::num=0; 也是可以的
void main()
{
A a;
a.show();
B b;
b.show();
B bb;
bb.show();
system("pause");
}
4、静态数据成员可以成为成员函数的确省参数,而普通数据成员则不可以
举例:
#include<iostream>
using namespace std;
class A
{
protected:
static int num;
public:
void count(int i=num)//通常确省参数给出的是数,这里可以使用静态成员
{
}
};
int A::num=0;
void main()
{
A a;
system("pause");
}
5、静态数据成员的类型可以是自己类的类型,而普通数据成员则不可以。普通数据成员的只能声明为 所属类类型的指针或引用。
举例:
class A
{
protected:
A aaa;//错误,普通数据成员不可以使用自己类作为类型名
A *b; //正确,普通成员可以使用自己类的指针
static A aa;//正确,静态成员函数可以使用自己类作为类型名
};
二、静态数据成员函数
为什么要引入静态数据成员:主要原因是为了取代全局函数,能在调用构造函数前(未初始化类之前)调用,通常CALLBACK函数中会用得到。
什么时候使用静态数据成员:为了访问全局变量或类的静态数据成员
语法:
定义:static + 普通成员函数定义
定义位置:可以在类内,也可以自类外。类外定义是不加static
使用:
类外使用:
访问规则:public
使用方式:类名::静态公有成员函数名(实参表);
注意:和普通的成员变量一样,如果是私有或受保护的,不能在类外直接使用
类中使用:
访问规则:public/protected/private(可以是任意方式定义)
使用方式:直接使用静态成员函数
性质:
1、没有this指针
2、只属于一个类。
3、一般情况下,静态成员函数不访问非静态成员函数,如果确实需要,则需要传入参数通过对象名访问。
4、静态成员函数不可以同时声明为virtual、const、volatile函数。
举例:
class A
{
virtual static void a();//错误
static void b() const;//错误
static void c() volatile;//错误
};
举例:
#include<iostream>
using namespace std;
class A
{
private:
int i;
static int j;
public:
A(int i=1)
{
this->i=i;
}
static void show();