对象的内存中包含了成员变量,不同的对象占用不同的内存,这使得不同对象的成员变量相互独立,他们的值不受其他对象的影响。那么有没有哪些属性或者方法是归所有对象拥有的?它就是静态成员。
静态成员就是在成员变量和成员函数前加上 static 关键字。静态成员提供了一个同类对象的共享机制,主要是用来解决对象与对象之间通信的问题。静态成员包括 静态成员变量 与 静态成员函数。
静态成员变量a
在一个类中,若将一个成员变量声明为 static,这种成员称为 静态成员变量。
与一般的数据成员不同,无论建立了多少个对象,静态成员变量都只有一个静态数据的拷贝,所有的对象都共享这些静态成员变量,都可以引用它。
静态成员变量必须在类中声明,在类外初始化,语法格式如下:
static <数据类型> <静态成员变量名>;
由于初始化是在类外进行的,所以调用时需要添加类名作为前缀,语法格式如下:
<数据类型> <类名>::<静态成员变量名> = 初始值;
静态成员变量既可以通过对象名访问,也可以通过类名访问,但要遵循 private、protected 和 public 关键字的访问权限限制。
-
通过对象访问静态成员变量时,调用与普通成员函数没有区别。如果是私有属性,则通过 get/set 方法访问或赋值,如果是公共属性,则可以直接使用
对象名.静态成员变量的形式。 -
通过类名访问静态成员变量时,需要添加类名前缀
类名::静态成员变量。
例如,Person 类中有一个用于统计创建了多少个对象的静态成员变量 total,代码如下:
#include <iostream>
using namespace std;
class Person {
public:
// 静态变量只能在类内声明
static int total;
// 构造函数
Person() {
// 每创建一个对象,total 自增 1
total++;
cout << "构造函数执行" << endl;
}
};
// 静态变量需要在类外初始化
int Person::total = 0;
int main() {
// 创建两个对象并打印静态属性的值
Person obj_1, obj_2;
cout << obj_1.total << endl;
// 再创建两个对象并通过类名打印静态属性的值
Person obj_3, obj_4;
cout << Person::total << endl;
return 0;
}
静态成员函数
静态成员变量也是有访问权限的,因此,私有权限下的静态成员变量就无法通过类的方式调用,例如,我们在 Person 类中添加静态属性 total 放置在私有权限中:
#include <iostream>
using namespace std;
class Person {
private:
// 私有静态属性
static int _total;
public:
// 构造函数
Person() {
// 每创建一个对象,_total 自增 1
_total++;
cout << "构造函数执行" << endl;
}
// 通过 get 方法获取 _total 的值
int get_total() {
return _total;
}
};
// 静态变量需要在类外初始化
int Person::_total = 0;
int main() {
// 创建两个对象并打印静态属性的值
Person obj_1, obj_2;
// 使用 get 方法可以通过对象调用
cout << obj_2.get_total() << endl;
// 再创建两个对象并通过类名打印静态属性的值
Person obj_3, obj_4;
// 不能通过类名调用
// cout << Person::get_total() << endl;
return 0;
}
虽然我们可以通过使用 get 方法的方式来获取 _total 属性的值,但是,依然不能使用类的方式调用。这个时候,我们就需要使用 静态成员函数。
在类定义中,前面有 static 说明的成员函数称为 静态成员函数。
静态成员函数使用方式和静态变量一样,同样在对象没有创建前,即可通过类名调用。
静态成员函数主要为了访问静态变量,不能访问普通成员变量(非静态成员)。
静态成员函数可以在类内定义,也可以在类外定义。在类外定义时,不需要添加 static 前缀。
因此,以上代码可以修改成下面这种形式:
#include <iostream>
using namespace std;
class Person {
private:
// 私有静态属性
static int _total;
int age;
public:
// 构造函数
Person() {
// 每创建一个对象,_total 自增 1
_total++;
cout << "构造函数执行" << endl;
}
// 通过 get 方法获取 _total 的值
// static int get_total() {
// return _total;
// }
// 类内声明
static int get_total();
};
// 类外定义,定义时不需要添加 static 前缀
int Person::get_total() {
// 静态函数不能访问普通成员变量(非静态成员)
// age += 1;
return _total;
}
// 静态变量需要在类外初始化
int Person::_total = 0;
int main() {
// 创建两个对象并打印静态属性的值
Person obj_1, obj_2;
// 使用 get 方法可以通过对象调用
cout << obj_2.get_total() << endl;
// 再创建两个对象并通过类名打印静态属性的值
Person obj_3, obj_4;
// 可以通过类名调用静态函数
cout << Person::get_total() << endl;
return 0;
}
注意
最后还有一点需要注意的是,静态成员函数没有 this 指针。