static作用来自博客
修饰普通变量,修改变量的存储区域和生命周期,使变量存储在静态区,在main函数运行前就分配了空间,如果有初始值就用初始值初始化它,如果没有初始值系统用默认值初始化它
修饰普通函数,表明函数的作用范围,仅在定义该函数的文件才能使用。在多人开发项目中,为了防止与他人明明空间里的函数重名,可以将函数定位为static
修饰成员变量,修饰成员变量使所有的对象只保存一个该变量,而且不需要生成对象就可以访问该成员
修饰成员函数,修饰成员函数使得不需要生成对象就可以访问该函数,但是在static函数内不能访问非静态成员
下面内容来自博客
C语言中的 static 关键字
修饰变量
静态全局变量:全局变量前加static修饰,该变量就成为静态全局变量。全局变量在整个工程内都能被访问(一个文件中定义,其他文件使用该变量的时候添加extern关键字声明)。添加static之后,变量只能在本文件内被访问,在此,static作用是限定作用域。
静态局部变量:static修饰局部变量,该变量就成为了静态局部变量。局部变量离开了被定义的函数之后会被销毁,而被static修饰了的局部变量,该变量的生命周期一直到程序运行结束,而跟函数是否被调用没有关系,但是该变量只能在该函数中访问。在此,static的作用是限定生命周期。
修饰函数
修饰函数则该函数成为静态函数,函数的作用域仅限于本文件,而不能被其他文件调用。
C++中的 static 关键字
类中的静态成员
1、用 static关键字 修饰;
2、可以用 类名::成员名 访问 静态成员;
3、静态成员 属于 整个类;
4、静态成员 是所属类的成员,其它类不能访问;
5、静态成员的内存分配 是 唯一的;
静态成员变量
特征:
1、静态成员变量 属于 整个类所有;
2、静态成员变量的生命周期不依赖任何对象;(静态成员变量的生命周期在程序的运行期)
3、所有对象共享类的静态成员变量;
4、可以通过 类名 直接访问公有的静态成员变量;
5、可以通过 对象名 访问公有的静态成员变量;
6、静态成员变量 需要在类外单独分配空间;(类内声明、类外定义并初始化)
7、静态成员变量 在程序内部位于全局数据区,不计入类的内存计算。
原因/好处:使用静态成员变量实现多个对象之间的数据共享不会破坏隐藏的原则,保证了安全性还可以节省内存。
使用方法:
1、在类的内部,使用 static 修饰普通成员变量;
2、在类的外部(全局作用域),使用 Type ClassName::VarName = value 初始化,并申请存储空间;
注:静态成员变量不属于类的任何对象,所以并不是对象建立时被定义的,所以它不能由类的构造函数初始化,一般也不能在类内初始化;
/*
静态成员变量 只能在类的内部声明,在类的外部(全局区)定义和初始化;
*/
#include <iostream>
using namespace std;
class Test{
public:
int GetA() const{return a;}
private:
static int a; // 静态成员变量
};
//int Test::a;如果这样定义不赋予初值,则初值为零
int Test::a = 1;
int main(int argc, char *argv[]){
Test T;
cout << T.GetA() << endl;
return 0;
}
静态成员变量被类的所有对象共享,包括派生类对象
#include <iostream>
using namespace std;
class Base{
public:
static int a; // 静态成员变量
};
// int Test::a;如果这样定义不赋予初值,则初值为零
int Base::a;
class Derived : public Base{
};
int main(int argc, char *argv[]){
Base B;
Derived D;
B.a++;
cout << B.a << endl; // 1
D.a++;
cout << D.a << endl; // 2
return 0;
}
静态成员变量可以作为普通成员函数的默认形参,而普通成员变量则不可以
class Test{
public:
static int a; //静态成员变量
int b;
void fun_1(int i = a); //正确
//void fun_2(int i = b); //报错
};
静态成员变量的类型可以是所属类的类型,而不同成员变量不可以。普通成员变量只能声明为所属类类型的指针或引用。
class Test{
public:
static Test a; //静态成员变量
//Test b;//报错
Test *pTest;//正确
Test &m_Test;//正确
static Test *pStaticObject;//正确
};
静态成员变量在const函数中可以修改,而普通的成员变量是万万不能修改的。
/*
* const修饰的是当前this指针所指向的对象是const,但是静态成员变量不属于任何类的对象,
* 它被类的所有对象修改,所以this指针不修饰静态的成员变量,所以可以更改。
*/
class Test{
public:
static int a;
int b;
public:
Test():b(0){}
void test() const{
a++;
//b++; // err // const指的是不能修改当前调用该函数对象的成员变量
}
};
int Test::a;
静态成员函数
特征:
静态成员函数属于整个类所有
所有对象共享类的静态成员函数
可以通过类名直接访问公有的静态成员函数
可以通过对象名访问公有的静态成员函数
静态成员函数只能访问静态成员,不能访问非静态成员
静态成员函数没有this指针,也就是说静态成员函数不能使用修饰符(也就是函数后边的const的关键字)
原因:
处理静态成员变量
使用方法:
直接用static修饰普通成员函数(类内声明时),(类外定义时不需要 static 修饰)
总结:
静态成员函数 | 普通成员函数 | |
---|---|---|
所有对象共享 | Yes | Yes |
隐含this指针 | No | Yes |
访问普通成员变量(函数) | No | Yes |
访问静态成员变量(函数) | Yes | Yes |
通过类名直接调用 | Yes | No |
通过对象直接调用 | Yes | Yes |
举例:
/**
* 统计某班选修课考试的平均成绩
*/
#include <iostream>
#include <string>
using namespace std;
class Student{
private:
string name; // 姓名
string gender; // 性别
float score; // 分数
string subject; // 课程
static int total_counts; // 总人数
static float chinese_scores; // 语文分数
static int chinese_counts; // 语文课人数
static float math_scores; // 数学分数
static int math_counts; // 数学课人数
public:
Student(string name, string gender, float score, string subject);
~Student();
static float aveScores(string subject);
void printStudentInfo();
void printAveScores();
};
int Student::total_counts = 0;
float Student::chinese_scores = 0;
int Student::chinese_counts = 0;
float Student::math_scores = 0;
int Student::math_counts = 0;
Student::Student(string name, string gender, float score, string subject){
this->name = name;
this->gender = gender;
this->score = score;
this->subject = subject;
if(subject == "chinese" || subject == "语文"){
chinese_scores += score;
chinese_counts++;
}
else if(subject == "math" || subject == "数学"){
math_scores += score;
math_counts++;
}
else{
cout << "this is no the subect:" << subject << endl;
}
total_counts += (chinese_counts + math_counts);
}
Student::~Student(){
total_counts--;
chinese_counts--;
math_counts--;
}
float Student::aveScores(string subject){
float ave_score = 0;
if(chinese_counts > 0 && subject == "chinese" || subject == "语文"){
ave_score = (chinese_scores / chinese_counts);
//cout << subject << "\t" << chinese_counts << "\t" << chinese_scores << endl;
}
else if(math_counts > 0 && subject == "math" || subject == "数学"){
ave_score = (math_scores / math_counts);
//cout << subject << "\t" <<math_counts << "\t" << math_scores << endl;
}
return ave_score;
}
void Student::printStudentInfo(){
cout << name << "\t" << gender << "\t" << score << "\t" << subject << endl;
}
void Student::printAveScores(){
cout <<subject << " average score: " << aveScores(subject) << endl;
}
int main(int argc, char const *argv[]){
const int SIZE = 5;
Student stu[SIZE] = {
Student("10001", "male", 92, "语文"),
Student("10002", "male", 91, "数学"),
Student("10003", "male", 91, "数学"),
Student("10004", "male", 93, "语文"),
Student("10005", "male", 92, "语文"),
};
for(int i = 0; i < SIZE; i++){
stu[i].printStudentInfo();
}
stu[0].printAveScores();
stu[1].printAveScores();
cout << "语文" << " average score: " << Student::aveScores("语文") << endl;
cout << "数学" << " average score: " << Student::aveScores("数学") << endl;
return 0;
}
/**
* 案例:有一场篮球赛,红队与蓝队各有5名队员,统计各个球队的得分情况(总分、平均分),并将获胜球队的球员信息输出
*/
#include <iostream>
#include <string>
using namespace std;
class Player{
public:
int number; // 编号
string gender; // 性别
int age; // 年龄
float score; // 个人分数
public:
Player(int number = 0, int age = 0, float score = 0, string gender = "male"){
this->number = number;
this->age = age;
this->score = score;
this->gender = gender;
}
};
class Team{
private:
string name; // 球队名称
int sum; // 球队总分
//static int COUNT; // 球队人数
static const int COUNT = 5; // 球队人数
Player player[COUNT]; // 球队队员信息
public:
Team(string name){
this->name = name;
for(int i = 0; i < Team::COUNT; i++){
player[i] = Player(10001 + i, 20 + i, 0);
}
}
string getName(){
return name;
}
static int playersCount(){
return COUNT;
}
int totalScore(){
sum = 0;
for(int i = 0; i < Team::COUNT; i++){
sum += player[i].score;
}
return sum;
}
float aveScore(){
if(sum == 0){
totalScore();
}
return (sum/Team::COUNT);
}
bool setPlayer(int index, int num, int age, float score, bool isMale = true){
bool ret = true;
if(Team::COUNT && index >= 0){
player[index].number = num;
player[index].age = age;
player[index].score = score;
isMale == true ? player[index].gender = "male" : player[index].gender = "female";
}
else{
cout << "the index of array is out of range, the max index should less than " << Team::COUNT << endl;
ret = false;
}
return ret;
}
bool PK(Team &team){
int ret = this->sum > team.sum;
if(ret){
cout << this->name + " 获胜" << endl;
}
else{
cout << team.name + " 获胜" << endl;
}
return ret;
}
void print(){
cout << "Team Name:" << name << endl;
for(int i = 0; i < Team::COUNT; i++){
cout << player[i].number << "\t" << player[i].gender << "\t" << player[i].age << "\t" << player[i].score << endl;
}
cout << name << " get total score:" << totalScore() << endl;
cout << name << " get average score:" << aveScore() << endl;
}
};
//int Team::COUNT = 5; // 初始化每支球队共有5名球员
int main(int argc, char *argv[])
{
Team t1("Red Team");
t1.setPlayer(0, 10001, 22, 91);
t1.setPlayer(1, 10003, 32, 93);
t1.setPlayer(2, 10005, 23, 94);
t1.setPlayer(3, 10007, 25, 95, false);
t1.setPlayer(4, 10009, 28, 88);
// t1.print();
// cout << t1.getName() << " get total score:" << t1.totalScore() << endl;
// cout << t1.getName() << " get average score:" << t1.aveScore() << endl;
cout << endl;
Team t2("Blue Team");
t2.setPlayer(0, 20001, 22, 81);
t2.setPlayer(1, 20003, 32, 83);
t2.setPlayer(2, 20005, 23, 84);
t2.setPlayer(3, 20007, 25, 85);
t2.setPlayer(4, 20009, 28, 88);
// t2.print();
// cout << t2.getName() << " get total score:" << t2.totalScore() << endl;
// cout << t2.getName() << " get average score:" << t2.aveScore() << endl;
if( t1.PK(t2) ){
t1.print();
}
else{
t2.print();
}
return 0;
}