一、对象的生产期
- 生存期:对象从诞生到结束的这段时间
- 生存期分为静态生存期和动态生存期
1.1 静态生存期
- 对象的生存期与程序的运行期相同,则称它具有静态生存期
- 在文件作用域中声明的对象都是具有静态生存期的
- 若在函数内部的局部作用域中声明具有静态生存期的对象,则要使用static关键字
- 局部作用域中静态变量的特点:
- 不会随着每次函数调用而产生一个副本,也不会随着函数返回而失效,该变量会在各次调用间共享
- 局部作用域中静态变量的特点:
1.2 动态生存期
- 非静态变量的对象都具有动态生存期
- 在局部作用域中声明的具有动态生存期的对象,也称为局部生存期对象,它诞生于声明点,结束于声明所在的块执行完毕之时
二、类的静态成员
2.1 类静态成员的特点
- 用关键字static声明
- 为该类的所有对象共享,静态数据成员具有静态生存周期
- 必须在类外定义和初始化,用 “ :: ” 来指明所属的类
- “ :: ” 是作用域操作符
2.2 为什么需要静态数据成员?
示例:
#include <iostream>
using namespace std;
// 一个点类,点的属性:坐标
class Point{
private:
int x, y;
public:
Point(int x = 0, int y = 0) : x(x), y(y){ }
~Point() { }
int getX() { return x; }
int getY() { return y; }
};
上述代码是一个点类的模板,每新创建一个点类对象都会调用一次上述函数
每个类的实例都创建都创建一个独立的对象,每个对象都复制了类的数据或属性
每个对象管理各自得属性值
-
假设增加一个需求:统计点的总个数。考虑添加一个计数的数据成员
-
要求:
- 必须在任何时候都能在每个Student对象中使用加法函数
- 当生成一个新的Student实例的时候,必须保证,所有Student对象都实现了总人数的计数
class Point{ private: int x, y; int count; // 用于记录点的个数 public: Point(int x = 0, int y = 0) : x(x), y(y){ } ~Point() { } int getX() { return x; } int getY() { return y; } void addCount() { count++; } void showCount() { count << " Object count = " << count << endl; } };
上述代码存在的问题:
- 每次新定义一个点类,都要手动的修改count值,定义第1个则count改为1,定义第2个则count改为2,同时要将第1个对象的count值改为2,定义第3个则count改为3,同时要将第1个和第2个对象的count值改为3……
解决办法:指定count为一个静态数据成员
- 局部静态变量的生存期域程序的运行时间相同
- count仍然是局部变量,可以看成是所有Point对象共享的一般变量
class Point{ private: int x, y; static int count; // 静态数据成员声明,用于记录点的个数 public: Point(int x = 0, int y = 0) : x(x), y(y){ count++; } // 每次创建对象时都会自动调用,自动将对象个数加1 ~Point() { count--; } // 每次撤销对象的时候自动调用,对象个数自动减1 int getX() { return x; } int getY() { return y; } void showCount() { count << " Object count = " << count << endl; } }; // 静态数据成员在类外定义和初始化,使用类名限定 int Point::count = 0; int main() { Point a(4, 5); // 定义对象a,其构造函数会使count加1 cout << "Point A: " << a.getX() << ", " << a.getY(); a.showCount(); // 输出对象个数 Point b; // 定义对象b,其构造函数会使count加1 cout << "Point B: " << b.getX() << ", " << b.getY(); b.showCount(); // 输出对象个数 return 0; }
三、静态成员函数
- 类外代码可以使用类名和作用域操作符来调用静态成员函数
- 静态成员函数只能引用属于该类的静态数据成员或静态成员函数
示例:
class Point{
private:
int x, y;
static int count; // 静态数据成员声明,用于记录点的个数
public:
Point(int x = 0, int y = 0) : x(x), y(y){ count++; } // 每次创建对象时都会自动调用,自动将对象个数加1
~Point() { count--; } // 每次撤销对象的时候自动调用,对象个数自动减1
int getX() { return x; }
int getY() { return y; }
static void showCount() {
count << " Object count = " << count << endl;
}
};
// 静态数据成员在类外定义和初始化,使用类名限定
int Point::count = 0;
int main() {
Point a(4, 5); // 定义对象a,其构造函数会使count加1
cout << "Point A: " << a.getX() << ", " << a.getY();
Point::showCount(); // 输出对象个数
Point b; // 定义对象b,其构造函数会使count加1
cout << "Point B: " << b.getX() << ", " << b.getY();
Point::showCount(); // 输出对象个数
return 0;
}