前言
一般情况下,如果有N个同类的对象,那么每一个对象都分别有自己的成员变量,不同对象的成员变量各自有值,互不相干。但是有时我们希望有某一个或几个成员变量为所有对象,这样可以实现数据共享。
可以使用全局变量来达到共享数据的目的。例如在一个程序文件中有多个函数,每一个函数都可以改变全局变量的值,全局变量的值为各函数共享。但是用全局变量的安全性得不到保证,由于在各处都可以自由的修改全局变量的值,很有可能偶然失误,全局变量的值就被修改,导致程序的失败。因此在实际开发中很少使用全局变量。
如果在同类的多个对象之间实现数据共享,也不要用全局变量,那么可以使用
静态成员变量
static成员变量
静态成员变量是一种特殊的成员变量,它以关键词 static 开头,例如:
class Student{
private:
string name;
int age;
float score;
static int number; //定义静态成员变量
public:
Student(string name,int age,float score);
Student(const Student & s);
~Student();
void setName(string n);
string getName();
void setAge(int a);
int getAge();
void setScore(float s);
float getScore();
};
Student::Student(string name,int age,float score){
name = name;
age = age;
score = score;
}
Student::Student(const Student & s){
this ->name = s.name;
this ->age = s.age;
this ->score = s.score;
}
Student::~Student(){}
string Student::getName(){
return this->name;
}
int Student::getAge(){
return this->age;
}
float Student::getScore(){
return this ->score;
}
void Student::setName(string n){
this ->name = n;
}
void Student::setAge(int a){
this ->age =a ;
}
void Student::setScore(float s){
this->score =s;
}
int Student::number = 0; //静态变量必须初始化,才可以使用
这段代码生命了一个静态成员变量number,用来统计学生的人数。
static 成员变量属于类,不属于某一个具体的对象(所以,在类的构造函数中,没有为这个变量赋值),这就意味着,即使创建多个对象,也只为numer 分配一份内存,所有对象使用的都是这份内存中的数据。当某一个对象修改了number,也会影响到其他对象。
static成员变量必须先初始化才能使用,否则链接错误。例如
int Student::number;
也可以在初始化赋值:
int Student::number = 0; //静态变量必须初始化,才可以使用
初始化时可以不加static,但是必须有数据类型。被 private、protected、public修饰的static成员变量都可以用这种初始化。
注意:static成员变量的内存空间既不是在声明类时分配的,也不是在创建对象时分配,而是在初始化时分配的。
注意:static 成员变量与对象无关,不占用对象的内存,而是在所有对象之外开辟内存,即使不创建对象也可以访问。
下面给出一个完整的例子:
#include<iostream>
#include<string>
using namespace std;
class Student{
private:
string name;
int age;
float score;
static int number; //定义静态成员变量
public:
Student(string name,int age,float score);
Student(const Student & s);
~Student();
void setName(string n);
string getName();
void setAge(int a);
int getAge();
void setScore(float s);
float getScore();
void say();
};
/*注意,如果构造函数的形参和 类的成员变量名字一样,必须采用 this -> name = name ,而不可以 写成 name = name*/
Student::Student(string name,int age,float score){
this->name = name;
this ->age = age;
this ->score = score;
number++;
}
Student::Student(const Student & s){
this ->name = s.name;
this ->age = s.age;
this ->score = s.score;
}
Student::~Student(){}
string Student::getName(){
return this->name;
}
int Student::getAge(){
return this->age;
}
float Student::getScore(){
return this ->score;
}
void Student::setName(string n){
this ->name = n;
}
void Student::setAge(int a){
this ->age =a ;
}
void Student::setScore(float s){
this->score =s;
}
void Student::say(){
cout << this->name <<" : " << this->age <<" : " << this ->score << " : " << Student::number <<endl;
}
int Student::number = 0; //静态便令必须初始化,才可以使用
int main(int argc,char*argv[])
{
Student s1("lixiaolong",32,100.0);
Student s2("chenglong",32,95.0);
Student s3("shixiaolong",32,87.0);
s1.say();
s2.say();
s3.say();
system("pause");
return 0;
}
总结:关于静态成员变量的几点说明:
1、一个类中可以有一个或多个静态成员变量,所有的对象都共享这些静态成员变量,都可以引用它。
2、static 成员变量和普通的static变量一样,编译的时候在静态数据区分配内存,到程序结束的时候才释放。这就意味着,static成员变量不随对象的创建而分配内存,也不会随对象的销毁而释放内存。而普通成员变量在对象创建的时候分配内存,在对象销毁的时候释放内存。
3、静态成员变量必须初始化,而且只能在类体外进行,例如:
int Student::number = 10;
c初始化的时候,可以赋初值,也可以不赋初值。如果不不赋初值,那么会默认初始化,一般为0。静态数据区的变量都有默认的初始值,而动态数据区(堆区,栈区)的变量默认是垃圾值。
4、静态成员变量既可以通过对象访问,也可以通过类名访问,但要遵循private、protected和 public关键字的访问权限设置。当通过对象访问的时候,对于不同的对象,访问的是同一份内存。