静态成员 —— 模拟共享书店
任务描述
本关任务:假设有一个这样的共享书店,当客户进入书店时需要托管一定数量的书籍,而这些书籍将被书店内所有用户共享,当客户离开书店时,他便会把之前进入书店托管的书一起带走。现请你编写代码设计这个共享书店。
相关知识
对象的内存中包含了成员变量,不同的对象占用不同的内存,这使得不同对象的成员变量相互独立,它们的值不受其他对象的影响。例如有两个相同类型的对象 a、b,它们都有一个成员变量 name,那么修改 a 对象的 name 值不会影响 b 中的 name 值。
可是有时候我们希望在多个对象之间共享数据,即对象 a 改变了某份数据后对象 b 可以检测到。共享数据的典型使用场景是计数。在 C++ 中,我们可以使用静态成员变量来实现多个对象共享数据的目标。
下面我们就一起之来学习静态成员的声明、定义及使用。
静态成员
静态成员变量是一种特殊的成员变量,它用关键字 static 来修饰。当我们声明类的成员为静态时,这意味着无论创建多少个类的对象,静态成员都只有一个副本,对它做出修改时所有对象都是可见的。
静态成员在类的所有对象中是共享的。声明一个静态成员与声明一个非静态成员(也叫实例成员)基本一致,只需要在声明的最前面加上一个 static 关键字即可。如果不存在其他的初始化语句,在创建第一个对象时,所有的静态数据都会被初始化为零。
例如:
class Test
{
public:
int A; // 实例成员
static int B; // 静态成员变量
static void Fun1(); // 静态成员函数
};
注意:静态成员也是有访问性的。
定义分成两部分,一是静态变量的初始化,二是静态函数的定义。
静态变量的初始化不能在类的定义中,但是可以在类的外部通过使用范围解析运算符::来重新声明静态变量从而对它进行初始化。而定义静态函数,那就与定义实例函数一样了。
例如:
class Test
{
public:
static string HelloStr;
static void Hello();
void World();
};
string Test::HelloStr = “Hello”; // 静态变量初始化
void Test::World() // 定义实例成员函数
{
cout<<“World”<<endl;
}
void Test::Hello() // 定义静态函数,与定义 World 函数形式一样
{
cout<<“Hello”<<endl;
}
访问静态成员
静态成员的访问有以下两种方法:
使用类型名::静态成员格式访问;
通过对象访问。
第一种访问方式可以将其看做是一个全局变量,只不过变量名要带上类型名::的前缀;第二种可以将其看做是对象中的一个实例成员。
例如:
/* Test类的定义同上文 */
int main()
{
cout << Test::HelloStr << endl; // 通过作用域运算符访问
Test::HelloStr = “World”; // 修改静态变量 HelloStr
Test t1;
cout << t1.HelloStr <<endl; // 通过对象访问
Test::Hello(); // 通过作用域运算符访问
t1.World(); // 通过对象访问
}
输出结果为:
Hello
World
Hello
World
注意第一、二行输出的差别,那是因为代码修改了所有对象共享的Test::HelloStr静态变量。
编程要求
在右侧编辑器中的Begin-End之间补充代码,设计一个 User 类(客户类),现有一个共享书店,该书店客户在进入书店时需要托管一定量的书籍,而这些书籍将由书店内所有用户共享,当客户离开书店时,他还是要将他进入书店时托管的书带走。设计时访问性可自主选择,具体要求如下:
姓名:string Name
托管的书籍量:int Books
带参构造函数:User(string name,int books),使用这两个参数初始化内部的两个成员,同时按照姓名 数量 进入的格式打印一条消息。
析构函数:~User(),按照姓名 数量 离开的格式打印一条消息。
静态成员函数:void GetState(),按照书店人数:用户总数,书店共享书数量:书籍总数,人均共享数量:人均书籍量的格式打印一条消息,其中人均书籍量只保留整数部分,具体请参考测试说明。
提示:可以增加 UserCount ,BookCount 两个静态变量用于记录已有用户数和已有书籍数。
测试说明
平台会对你编写的代码进行测试,比对你输出的数值与实际正确数值,只有所有数据全部计算正确才能通过测试:
测试输入:厉宏富 10 冷欣荣 2 叶文光 0
预期输出:
厉宏富 10 进入
冷欣荣 2 进入
书店人数:2,书店共享书数量:12,人均共享数量:6
厉宏富 10 离开
叶文光 0 进入
书店人数:2,书店共享书数量:2,人均共享数量:1
冷欣荣 2 离开
书店人数:1,书店共享书数量:0,人均共享数量:0
叶文光 0 离开
下面展示一些 内联代码片
。
#include <string>
#include <iostream>
using namespace std;
/********* Begin *********/
class User
{
//在此处声明所需的成员
public:
static int UserCount;
static int BookCount;
string Name;
int Books;
User(string name,int books);
~User();
static void GetState();
};
int User::UserCount=0;
int User::BookCount=0;
User::User(string name,int books)
{
UserCount++;
Name=name;
Books=books;
cout<<Name<<" "<<Books<<" "<<"进入"<<endl;
BookCount+=Books;
}
User::~User()
{
UserCount--;
cout<<Name<<" "<<Books<<" "<<"离开"<<endl;
BookCount-=Books;
}
void User::GetState()
{
cout<<"书店人数:"<<User::UserCount<<","<<"书店共享书数量:"<<User::BookCount<<","<<"人均共享数量:"<<User::BookCount/User::UserCount<<endl;
}
/********* End *********/