在类定义中,它的成员(包括成员变量和成员函数),这些成员可以用关键字static声明为静态的,称为静态成员。
不管这个类创建了多少个对象,静态成员只有一个拷贝,这个拷贝被所有属于这个类的对象共享。
1. 静态成员变量
在一个类中,若将一个成员变量声明为static,这种成员称为静态成员变量。与一般的数据成员不同,无论建立了多少个对象,都只有一个静态数据的拷贝。静态成员变量,属于某个类,所有对象共享。
静态变量,是在编译阶段就分配空间,对象还没有创建时,就已经分配空间。
- 静态成员变量必须在类中声明,在类外定义。
- 静态数据成员不属于某个对象,在为对象分配空间中不包括静态成员所占空间。
- 静态数据成员可以通过类名或者对象名来引用。
class Person{ public: //类的静态成员属性 static int sNum; private: static int sOther; }; //类外初始化,初始化时不加static int Person::sNum = 0; int Person::sOther = 0; int main(){ //1. 通过类名直接访问 Person::sNum = 100; cout << "Person::sNum:" << Person::sNum << endl; //2. 通过对象访问 Person p1, p2; p1.sNum = 200; cout << "p1.sNum:" << p1.sNum << endl; cout << "p2.sNum:" << p2.sNum << endl; //3. 静态成员也有访问权限,类外不能访问私有成员 //cout << "Person::sOther:" << Person::sOther << endl; Person p3; //cout << "p3.sOther:" << p3.sOther << endl; system("pause"); return EXIT_SUCCESS; }
2. 静态成员函数
在类定义中,前面有static说明的成员函数称为静态成员函数。静态成员函数使用方式和静态变量一样,同样在对象没有创建前,即可通过类名调用。静态成员函数主要为了访问静态变量,但是,不能访问普通成员变量。
静态成员函数的意义,不在于信息共享,数据沟通,而在于管理静态数据成员,完成对静态数据成员的封装。
- 静态成员函数只能访问静态变量,不能访问普通成员变量
- 静态成员函数的使用和静态成员变量一样
- 静态成员函数也有访问权限
- 普通成员函数可访问静态成员变量、也可以访问非经常成员变量
class Person{ public: //普通成员函数可以访问static和non-static成员属性 void changeParam1(int param){ mParam = param; sNum = param; } //静态成员函数只能访问static成员属性 static void changeParam2(int param){ //mParam = param; //无法访问 sNum = param; } private: static void changeParam3(int param){ //mParam = param; //无法访问 sNum = param; } public: int mParam; static int sNum; }; //静态成员属性类外初始化 int Person::sNum = 0; int main(){ //1. 类名直接调用 Person::changeParam2(100); //2. 通过对象调用 Person p; p.changeParam2(200); //3. 静态成员函数也有访问权限 //Person::changeParam3(100); //类外无法访问私有静态成员函数 //Person p1; //p1.changeParam3(200); return EXIT_SUCCESS; }
3. const静态成员属性
如果一个类的成员,既要实现共享,又要实现不可改变,那就用 static const 修饰。定义静态const数据成员时,最好在类内部初始化。
class Person{ public: //static const int mShare = 10; const static int mShare = 10; //只读区,不可修改 }; int main(){ cout << Person::mShare << endl; //Person::mShare = 20; return EXIT_SUCCESS; }
4. 静态成员实现单例模式
单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。
Singleton(单例): 在单例类的内部实现只生成一个实例,同时它提供一个静态的getInstance()工厂方法,让客户可以访问它的唯一实例;为了防止在外部对其实例化,将其默认构造函数和拷贝构造函数设计为私有;在单例类内部定义了一个Singleton类型的静态对象,作为外部共享的唯一实例。
用单例模式,模拟公司员工使用打印机场景,打印机可以打印员工要输出的内容,并且可以累积打印机使用次数。
class Printer{ public: static Printer* getInstance(){ return pPrinter;} void PrintText(string text){ cout << "打印内容:" << text << endl; cout << "已打印次数:" << mTimes << endl; cout << "--------------" << endl; mTimes++; } private: Printer(){ mTimes = 0; } Printer(const Printer&){} private: static Printer* pPrinter; int mTimes; }; Printer* Printer::pPrinter = new Printer; void test(){ Printer* printer = Printer::getInstance(); printer->PrintText("离职报告!"); printer->PrintText("入职合同!"); printer->PrintText("提交代码!"); }