静态数据成员和静态成员函数、常量
一、静态数据成员
1.定义:
要对静态数据成员定义和初始化必须在类的外面也就是在全局作用域中定义,如果定义不给出初值,则默认初值为0。
class Test{ public: int GetA() const{return a;} private: //静态数据成员 static int a; }; //int Test::a;如果这样定义不赋予初值则初值为零 int Test::a = 1; #include <iostream> int main() { Test T; std::cout << T.GetA() << std::endl; }
定义时一定要在全局作用域中定义,一定不要在类中定义!
静态数据成员甚至在类没有任何对象的时候都可以访问,静态成员可以独立访问,无需依赖任何对象的建立
2.静态数据成员可以作为成员函数的默认形参,而普通数据成员则不可以
class Test{ public: //静态数据成员 static int a; int b; void fun_1(int i = a);//正确 void fun_2(int i = b);//报错 };
3.静态数据成员在const函数中可以修改,而普通的数据成员是不能修改的!
class Test{ public: Test():b(0){} //静态数据成员 static int a;//正确 int b; void test() const { a++; b++;//const指的不能修改当前调用该函数对象的数据成员 } }; int Test::a;
const修饰的时当前this指针所指向的对象是const,但是静态数据成员不属于任何类的对象,它被类的所有对象修改,所以this指针不修饰静态的数据成员,所以可以更改。
二、静态成员函数
静态成员函数的声明也很简单,就是在类的成员函数前加上static关键字即可,和静态成员一样,静态成员函数也是属于类的,它并不属于任何对象,当调用静态成员函数时应该使用类名和域运算符“∷”,当然也可以使用对象调用操作,但是这样的操作并不意味着静态成员函数属于这个对象,它只是被这个对象共享而已,这样也就决定了静态成员函数中是不能访问本类中的非静态数据成员的,它是不能访问非静态数据成员的,在c++中静态成员函数主要用来访问静态数据成员而不访问非静态数据成员
1.静态成员函数不能调用非静态成员函数,但是反过来是可以的
2.静态成员函数没有this指针,也就是说静态成员函数不能使用修饰符(也就是函数后面的const关键字)
3.静态成员函数的地址可用普通函数指针储存,而普通成员函数地址需要用 类成员函数指针来储存。
//定义Student类 #include <iostream> class Student { public: //定义构造函数 Student(int n,int a,float s):num(n),age(a),score(s){ } void total(); //声明静态成员函数 static float average(); private: int num; int age; float score; //静态数据成员,累计学生的总分 static float sum; //静态数据成员,累计学生的人数 static int count; }; //在全局作用域对静态数据成员初始化,如果不赋予初值,则使用其默认值零 float Student::sum; int Student::count; //定义非静态成员函数 void Student::total() { //累加总分 sum+=score; //累计已统计的人数 count++; } //定义静态成员函数 float Student::average() { return(sum/count); } int main() { Student stud[3]={ //定义对象数组并初始化 Student(1001,18,70), Student(1002,19,78), Student(1005,20,98) }; int n; std::cout<<"please input the number of students: "; //输入需要求前面多少名学生的平均成绩 std::cin>>n; //调用3次total函数 for(int i=0;i<n;i++) { stud[i].total(); } //调用静态成员函数 std::cout<<"the average score of "<<n<<" students is "<<Student::average( )<<std::endl; return 0; }
三、static和const的区别:
static:
- static局部变量 将一个变量声明为函数的局部变量,那么这个局部变量在函数执行完成之后不会被释放,而是继续保留在内存中
- static 全局变量 表示一个变量在当前文件的全局内可访问
- static 函数 表示一个函数只能在当前文件中被访问
- static 类成员变量 表示这个成员为全类所共有
- static 类成员函数 表示这个函数为全类所共有,而且只能访问静态成员变量
const:
- const 常量:定义时就初始化,以后不能更改。
- const 形参:func(const int a){};该形参在函数里不能改变
- const修饰类成员函数:该函数对成员变量只能进行只读操作
static关键字的作用:
(1)函数体内static变量的作用范围为该函数体,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;
(2)在模块内的static全局变量和函数可以被模块内的函数访问,但不能被模块外其它函数访问;
(3)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;
(4)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。
const关键字的作用:
(1)阻止一个变量被改变
(2)声明常量指针和指针常量
(3)const修饰形参,表明它是一个输入参数,在函数内部不能改变其值;
(4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;
(5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为”左值”。