C++ 核心案例 —— 基于多态的职工管理系统

创建管理类

管理类实现如下内容:

》》》与用户的沟通菜单界面

》》》对职工增删改查的操作

》》》与文件的读写交互

具体步骤

第一步:在头文件和源文件夹下分别创建 workerManager.h 和 workerManager.cpp 文件

在这里插入图片描述
第二步:头文件 workerManager.h 实现

#pragma once // 防止头文件重复包含
#include <iostream>
using namespace std;

class WorkerManager {
public:
	// 构造函数
	WorkerManager();
	// 析构函数
	~WorkerManager();
};

第三步:源文件 workerManager.cpp 实现

#include "workerManager.h"

WorkerManager::WorkerManager() {

}

WorkerManager::~WorkerManager() {

}

实现菜单功能

第一步:在管理类 workerManager.h 中添加成员函数 void Show_Menu();

#pragma once // 防止头文件重复包含
#include <iostream>
using namespace std;

class WorkerManager {
public:
	// 构造函数
	WorkerManager();
	// 显示菜单
	void Show_Menu();
	// 析构函数
	~WorkerManager();
};

第二步:在管理类 workerManager.cpp 中实现 void Show_Menu(); 函数

#include "workerManager.h"

void WorkerManager::Show_Menu() {
	cout << "*************************************" << endl;
	cout << "******** 欢迎使用职工管理系统! *****" << endl;
	cout << "*********  0.退出管理系统  **********" << endl;
	cout << "*********  1.增加职工信息  **********" << endl;
	cout << "*********  2.显示职工信息  **********" << endl;
	cout << "*********  3.删除职工信息  **********" << endl;
	cout << "*********  4.修改职工信息  **********" << endl;
	cout << "*********  5.查找职工信息  **********" << endl;
	cout << "*********  6.按照编号排序  **********" << endl;
	cout << "*********  7.清空所有文档  **********" << endl;
	cout << "*************************************" << endl;
}

第三步:在 职工管理系统.cpp 中测试菜单功能

#include <iostream>
using namespace std;
#include "workerManager.h"

int main() {

	WorkerManager wm;

	wm.Show_Menu();

	system("pause");
	return 0;
}

测试结果

在这里插入图片描述

实现退出功能

第一步:在 workerManager.h 文件中提供退出系统的函数 void exitSystem();

第二步:在 workerManager.cpp 文件中完成此函数的具体实现

void WorkerManager::exitSystem() {
	cout << "欢迎下次使用!" << endl;
	system("pause");
	exit(0); // 程序退出
}

第三步:在 main 主函数中提供分支选择,实现每个功能的接口

#include <iostream>
using namespace std;
#include "workerManager.h"

int main() {

	WorkerManager wm;
	int choice = 0; // 分支选择
	while (true) {
		// 显示菜单
		wm.Show_Menu();
		cout << "请输入您的选择:";
		cin >> choice;

		// 选择语句
		switch (choice) {
		case 0: // 退出系统
			wm.exitSystem();
			break;
		case 1: // 添加职工
			break;
		case 2: // 显示职工
			break;
		case 3: // 删除职工
			break;
		case 4: // 修改职工
			break;
		case 5: // 查找职工
			break;
		case 6: // 排序职工
			break;
		case 7: // 清空文件
			break;
		default:
			system("cls"); // 清屏
			break;
		}
	}

	system("pause");
	return 0;
}

实现职工类

职工的分类:普通员工、经理和老板

》》》将三种职工抽象到一个类(Worker)中,利用多态管理不同职工类

职工属性: 职工编号、职工姓名和职工所在部门编号

职工行为: 岗位职责信息描述的函数、获取岗位名称的成员函数


具体步骤(普通员工)

第一步(实现职工抽象类):创建文件 worker.h 并添加如下代码

#pragma once
#include <iostream>
#include <string>
using namespace std;

// 职工抽象类
class Worker {
public:
	// 纯虚函数
	// 显示个人信息
	virtual void showInfo() = 0;
	// 获取岗位信息
	virtual string getDeptName() = 0;

public:
	int Id_; // 职工编号
	string Name_; // 职工姓名
	int DeptId_; // 职工所在部门编号
};

第二步(实现普通员工类):创建文件 employee.h 并添加如下代码

#pragma once
#include <iostream>
#include "worker.h"

// 员工类
class Employee :public Worker{
public:
	// 构造函数
	Employee(int id, string name, int dId);
	// 显示个人信息
	virtual void showInfo();
	// 获取职工岗位名称
	virtual string getDeptName();
};

第三步(实现普通员工类):创建文件 employee.cpp 并添加如下代码

#include "employee.h"

Employee::Employee(int id, string name, int dId) {
	this->Id_ = id;
	this->Name_ = name;
	this->DeptId_ = dId;
}

void Employee::showInfo() {
	cout << "职工编号:" << this->Id_
		<< "\t职工姓名:" << this->Name_
		<< "\t岗位:" << this->DeptId_
		<< "\t岗位职责:完成经理交给的问题" << endl;
}

string Employee::getDeptName() {
	return string("员工");
}

第四步:在 职工管理系统.cpp 中添加测试函数用来测试多态

#include <iostream>
using namespace std;
#include "workerManager.h"
#include "employee.h"

void func() {
	Worker *worker = NULL;
	worker = new Employee(1, "苏苏", 3);
	worker->showInfo();
	// output:职工编号:1     职工姓名:苏苏  岗位:3 岗位职责:完成经理交给的问题
	delete worker;
}

int main() {

	func();

	system("pause");
	return 0;
}

在如上的基础上,我们能轻易实现经理类和老板类的

》》》实现经理类

第一步:创建文件 manager.h 并添加如下代码

#pragma once
#include <iostream>
#include "worker.h"

// 经理类
class Manager :public Worker {
public:
	// 构造函数
	Manager(int id, string name, int dId);
	// 显示个人信息
	virtual void showInfo();
	// 获取职工岗位名称
	virtual string getDeptName();
};

第二步:创建文件 manager.cpp 并添加如下代码

#include "manager.h"

Manager::Manager(int id, string name, int dId) {
	this->Id_ = id;
	this->Name_ = name;
	this->DeptId_ = dId;
}

void Manager::showInfo() {
	cout << "职工编号:" << this->Id_
		<< "\t职工姓名:" << this->Name_
		<< "\t岗位:" << this->DeptId_
		<< "\t岗位职责:完成老板交给的问题" << endl;
}

string Manager::getDeptName() {
	return string("经理");
}

》》》实现老板类

第一步:创建文件 boss.h 并添加如下代码

#pragma once
#include <iostream>
#include "worker.h"

// 老板类
class Boss :public Worker {
public:
	// 构造函数
	Boss(int id, string name, int dId);
	// 显示个人信息
	virtual void showInfo();
	// 获取职工岗位名称
	virtual string getDeptName();
};

第二步:创建文件 boss.cpp 并添加如下代码

#include "boss.h"

Boss::Boss(int id, string name, int dId) {
	this->Id_ = id;
	this->Name_ = name;
	this->DeptId_ = dId;
}

void Boss::showInfo() {
	cout << "职工编号:" << this->Id_
		<< "\t职工姓名:" << this->Name_
		<< "\t岗位:" << this->DeptId_
		<< "\t岗位职责:管理公司所有事务" << endl;
}

string Boss::getDeptName() {
	return string("员工");
}

综合测试案例

#include <iostream>
using namespace std;
#include "workerManager.h"
#include "employee.h"
#include "manager.h"
#include "boss.h"

void func() {
	Worker *worker = NULL;
	worker = new Employee(1, "苏苏", 3);
	worker->showInfo();
	delete worker;

	worker = new Manager(2, "柯柯", 2);
	worker->showInfo();
	delete worker;

	worker = new Boss(3, "梅梅", 1);
	worker->showInfo();
	delete worker;
	// outputs:职工编号:1     职工姓名:苏苏  岗位:3 岗位职责:完成经理交给的问题
	//		   职工编号:2     职工姓名:柯柯  岗位:2 岗位职责:完成老板交给的问题
	//	       职工编号:3     职工姓名:梅梅  岗位:1 岗位职责:管理公司所有事务
}

int main() {

	func();

	system("pause");
	return 0;
}

实现添加职工功能

功能描述:批量添加职工,并且保存到文件中

分析:

》》》用户在批量创建职工时,可能会创建不同种类的职工

》》》如果想将所有不同种类的员工放入一个数组中,那么可以将所有员工的指针维护到一个数组中

》》》如果想在程序中维护这个不定长的数组,那么可以将数组开辟到堆区,并利用指针 Worker ** 来维护

具体步骤

第一步:在 workerManager.h 中添加成员(补充头文件)

#include "worker.h"
#include "manager.h"
#include "boss.h"

class WorkerManager {
	// 记录文件中人的数量
	int EmpNum_;
	// 员工数组的指针
	Worker ** EmpArray_;
	// 增加成员
	void Add_Emp();
}

第二步:修改并补充 workerManager.cpp 文件中代码

#include "workerManager.h"

WorkerManager::WorkerManager() {
	// 初始化人数
	this->EmpNum_ = 0;
	// 初始化数组指针
	this->EmpArray_ = NULL;
}

void WorkerManager::Add_Emp() {
	cout << "请输入增加职工数量:";
	int addNum = 0;
	cin >> addNum;

	if (addNum > 0) {
		// 计算新空间大小
		int newSize = this->EmpNum_ + addNum;
		// 开辟新空间
		Worker ** newSpace = new Worker*[newSize];
		// 将原空间下数据存放到新空间下
		if (this->EmpArray_ != NULL) {
			for (int i = 0; i < this->EmpNum_; i++) {
				newSpace[i] = this->EmpArray_[i];
			}
		}
		// 输入并添加新数据
		for (int i = 0; i < addNum; i++) {
			int id;
			string name;
			int dId;

			cout << "请输入第 " << i + 1 << " 个新职工编号:";
			cin >> id;
			cout << "请输入第 " << i + 1 << " 个新职工姓名:";
			cin >> name;
			
			cout << "请选择新职工的岗位:" << endl;
			cout << "1. 普通职工" << endl;
			cout << "2. 经理" << endl;
			cout << "3. 老板" << endl;
			cin >> dId;

			Worker * worker = NULL;
			switch (dId) {
			case 1:
				worker = new Employee(id, name, dId);
				break;
			case 2:
				worker = new Manager(id, name, dId);
				break;
			case 3:
				worker = new Boss(id, name, dId);
				break;
			}
			// 添加新数据
			newSpace[this->EmpNum_ + i] = worker;
		}

		// 释放原有空间
		delete[]this->EmpArray_;
		// 更改新空间的指向
		this->EmpArray_ = newSpace;
		// 更新职工数目
		this->EmpNum_ = newSize;
		// 提示信息
		cout << "成功添加 " << addNum << " 名新职工!" << endl;
	}
	else {
		cout << "输入有误!" << endl;
	}

	system("pause");
	system("cls");
}

第三步:在 职工管理系统.cpp 文件中调用 Add_Emp(); 函数

#include <iostream>
using namespace std;
#include "workerManager.h"
#include "employee.h"
#include "manager.h"
#include "boss.h"

int main() {

	WorkerManager wm;
	int choice = 0; // 分支选择
	while (true) {
		// 显示菜单
		wm.Show_Menu();
		cout << "请输入您的选择:";
		cin >> choice;

		// 选择语句
		switch (choice) {
		case 0: // 退出系统
			wm.exitSystem();
			break;
		case 1: // 添加职工
			wm.Add_Emp();
			break;
		case 2: // 显示职工
			break;
		case 3: // 删除职工
			break;
		case 4: // 修改职工
			break;
		case 5: // 查找职工
			break;
		case 6: // 排序职工
			break;
		case 7: // 清空文件
			break;
		default:
			system("cls"); // 清屏
			break;
		}
	}

	system("pause");
	return 0;
}

文件交互 - 写文件

在上一个添加功能中,我们只是将所有数据都添加到了内存中,一旦程序结束就无法保存了

》》》因此文件管理类中需要一个与文件进行交互的功能,对文件进行读写操作

具体步骤

第一步:在 workerManager.h 文件中设定宏常量并且包含头文件 fstream

#include <fstream>
#define FILENAME "EmpFile.txt"

第二步:在 workerManager.h 文件中添加成员函数 void Save();

WorkerManager::WorkerManager() {
	// 保存文件
	void Save();
}

第三步:在 workerManager.cpp 文件中实现功能

void WorkerManager::Save() {
	ofstream ofs; // 流对象
	ofs.open(FILENAME, ios::out); // 写入数据

	for (int i = 0; i < this->EmpNum_; i++) {
		ofs << this->EmpArray_[i]->Id_ << " "
			<< this->EmpArray_[i]->Name_ << " "
			<< this->EmpArray_[i]->DeptId_ << " " << endl;
	}

	ofs.close(); // 关闭文件
}

第四步:在 Add_Emp(); 函数中补充一段代码 this->Save();

void WorkerManager::Add_Emp() {
	cout << "请输入增加职工数量:";
	int addNum = 0;
	cin >> addNum;

	if (addNum > 0) {
		// 计算新空间大小
		int newSize = this->EmpNum_ + addNum;
		// 开辟新空间
		Worker ** newSpace = new Worker*[newSize];
		// 将原空间下数据存放到新空间下
		if (this->EmpArray_ != NULL) {
			for (int i = 0; i < this->EmpNum_; i++) {
				newSpace[i] = this->EmpArray_[i];
			}
		}
		// 输入并添加新数据
		for (int i = 0; i < addNum; i++) {
			int id;
			string name;
			int dId;

			cout << "请输入第 " << i + 1 << " 个新职工编号:";
			cin >> id;
			cout << "请输入第 " << i + 1 << " 个新职工姓名:";
			cin >> name;
			
			cout << "请选择新职工的岗位:" << endl;
			cout << "1. 普通职工" << endl;
			cout << "2. 经理" << endl;
			cout << "3. 老板" << endl;
			cin >> dId;

			Worker * worker = NULL;
			switch (dId) {
			case 1:
				worker = new Employee(id, name, dId);
				break;
			case 2:
				worker = new Manager(id, name, dId);
				break;
			case 3:
				worker = new Boss(id, name, dId);
				break;
			}
			// 添加新数据
			newSpace[this->EmpNum_ + i] = worker;
		}

		// 释放原有空间
		delete[]this->EmpArray_;
		// 更改新空间的指向
		this->EmpArray_ = newSpace;
		// 更新职工数目
		this->EmpNum_ = newSize;
		// 提示信息
		cout << "成功添加 " << addNum << " 名新职工!" << endl;
		this->Save();
	}
	else {
		cout << "输入有误!" << endl;
	}

	system("pause");
	system("cls");
}

文件交互 - 读文件

虽然实现了添加职工后保存到文件的操作,但是每次开始运行程序,并没有将文件中的内存读取到程序中(而我们的程序中还有清空文件的需求)

因此构造函数初始化的方法有三种

》》》第一次使用,文件未创建时

》》》文件存在,但是数据被用户清空

》》》文件存在,并保存了职工的所有数据

具体步骤(文件为空或文件不存在)

第一步:在 workerManager.h 文件中添加成员属性 FileIsEmpty_ 来表示文件是否为空

class WorkerManager {
	// 标志文件是否为空
	bool FileIsEmpty_;
}

第二步:修改 workerManager.cpp 文件中构造函数的代码

WorkerManager::WorkerManager() {
	ifstream ifs; // 流对象
	ifs.open(FILENAME, ios::in);

	// 1. 文件不存在情况
	if (!ifs.is_open()) {
		cout << "文件不存在" << endl;
		// 初始化人数
		this->EmpNum_ = 0;
		// 初始化文件为空标志
		this->FileIsEmpty_ = true;
		// 初始化数组指针
		this->EmpArray_ = NULL;
		ifs.close(); // 关闭文件
		return;
	}
	
	// 2. 文件存在但数据为空
	char ch;
	ifs >> ch;
	if (ifs.eof()) {
		cout << "文件为空!" << endl;
		this->EmpNum_ = 0;
		this->FileIsEmpty_ = true;
		this->EmpArray_ = NULL;
		ifs.close(); // 关闭文件
		return;
	}
}

具体步骤(文件存在且数据不为空)

第一步:在 workerManager.h 中添加成员函数 int get_EmpNum();

class WorkerManager {
	// 获取职工数目
	int get_EmpNum();
}

第二步:在 workerManager.cpp 中完成相关实现

int WorkerManager::get_EmpNum() {
	ifstream ifs;
	ifs.open(FILENAME, ios::in);

	int id;
	string name;
	int dId;

	int num = 0;

	while (ifs >> id && ifs >> name && ifs >> dId) {
		// 记录人数
		num++;
	}

	ifs.close();
	return num;
}

第三步:在 职工管理系统.cpp 构造函数中继续完成相关实现

WorkerManager::WorkerManager() {
	ifstream ifs; // 流对象
	ifs.open(FILENAME, ios::in);

	// 1. 文件不存在情况
	if (!ifs.is_open()) {
		// cout << "文件不存在" << endl; // 测试代码
		// 初始化人数
		this->EmpNum_ = 0;
		// 初始化文件为空标志
		this->FileIsEmpty_ = true;
		// 初始化数组指针
		this->EmpArray_ = NULL;
		ifs.close(); // 关闭文件
		return;
	}

	// 2. 文件存在并且没有记录
	char ch;
	ifs >> ch;
	if (ifs.eof()) {
		// cout << "文件为空!" << endl; // 测试代码
		this->EmpNum_ = 0;
		this->FileIsEmpty_ = true;
		this->EmpArray_ = NULL;
		ifs.close(); // 关闭文件
		return;
	}

	// 3. 文件存在且有记录
	int num = this->get_EmpNum();
	// cout << "职工个数为:" << num << endl; // 测试代码
	this->EmpNum_ = num; // 更新成员属性
}

第四步(初始化数组):在 workerManager.h 中添加成员函数 void init_Emp();

class WorkerManager {
	// 初始化员工
	void init_Emp();
}

第五步:在 workerManager.cpp 中实现函数功能

void WorkerManager::init_Emp() {
	ifstream ifs;
	ifs.open(FILENAME, ios::in);

	int id;
	string name;
	int dId;

	int index = 0;
	while (ifs >> id && ifs >> name && ifs >> dId) {
		Worker *worker = NULL;
		// 根据不同部门的 Id 创建不同对象
		if (dId == 1) {
			worker = new Employee(id, name, dId);
		}
		else if (dId == 2) {
			worker = new Manager(id, name, dId);
		}
		else {
			worker = new Boss(id, name, dId);
		}

		// 存放在数组中
		this->EmpArray_[index] = worker;
		index++;
	}
}

第五步:在 workerManager.h 中追加代码

WorkerManager::WorkerManager() {
	ifstream ifs; // 流对象
	ifs.open(FILENAME, ios::in);

	// 1. 文件不存在情况
	if (!ifs.is_open()) {
		// cout << "文件不存在" << endl; // 测试代码
		// 初始化人数
		this->EmpNum_ = 0;
		// 初始化文件为空标志
		this->FileIsEmpty_ = true;
		// 初始化数组指针
		this->EmpArray_ = NULL;
		ifs.close(); // 关闭文件
		return;
	}

	// 2. 文件存在并且没有记录
	char ch;
	ifs >> ch;
	if (ifs.eof()) {
		// cout << "文件为空!" << endl; // 测试代码
		this->EmpNum_ = 0;
		this->FileIsEmpty_ = true;
		this->EmpArray_ = NULL;
		ifs.close(); // 关闭文件
		return;
	}

	// 3. 文件存在且有记录
	int num = this->get_EmpNum();
	// cout << "职工个数为:" << num << endl; // 测试代码
	this->EmpNum_ = num; // 更新成员属性
	this->EmpArray_ = new Worker *[this->EmpNum_];
	// 初始化职工
	this->init_Emp();
}

实现显示职工功能

第一步:在 workerManager.h 声明函数 void Show_Emp();

class WorkerManager {
	// 显示职工
	void Show_Emp();
}

第二步:在 workerManager.cpp 实现此函数的功能

void WorkerManager::Show_Emp() {
	if (this->FileIsEmpty_) {
		cout << "文件不存在或文件为空!" << endl;
	}
	else {
		for (int i = 0; i < this->EmpNum_; i++) {
			// 利用多态调用接口
			this->EmpArray_[i]->showInfo();
		}
	}

	system("pause");
	system("cls");
}

第二步:在 职工管理系统.cpp 绑定显示功能

#include <iostream>
using namespace std;
#include "workerManager.h"
#include "employee.h"
#include "manager.h"
#include "boss.h"

int main() {

	WorkerManager wm;
	int choice = 0; // 分支选择
	while (true) {
		// 显示菜单
		wm.Show_Menu();
		cout << "请输入您的选择:";
		cin >> choice;

		// 选择语句
		switch (choice) {
		case 0: // 退出系统
			wm.exitSystem();
			break;
		case 1: // 添加职工
			wm.Add_Emp();
			break;
		case 2: // 显示职工
			wm.Show_Emp();
			break;
		case 3: // 删除职工
			break;
		case 4: // 修改职工
			break;
		case 5: // 查找职工
			break;
		case 6: // 排序职工
			break;
		case 7: // 清空文件
			break;
		default:
			system("cls"); // 清屏
			break;
		}
	}

	system("pause");
	return 0;
}

实现删除职工功能

第一步:在 workerManager.h 完成函数声明 void Del_Emp();

class WorkerManager {
	// 删除职工
	void Del_Emp();
}

第二步:在 workerManager.h 完成函数声明 int IsExist(int id); 用来判断职工是否存在

class WorkerManager {
	// 判断职工是否存在
	int IsExist(int id);
}

第三步(返回的是需要删除职工的编号):在 workerManager.cpp 实现 int IsExist(int id);

int WorkerManager::IsExist(int id) {
	int index = -1;

	for (int i = 0; i < this->EmpNum_; i++) {
		if (this->EmpArray_[i]->Id_ == id) {
			index = i;
			break;
		}
	}
	return index;
}

第四步:在 workerManager.cpp 实现 void Del_Emp();

void WorkerManager::Del_Emp() {
	if (this->FileIsEmpty_) {
		cout << "文件为空或者不存在!" << endl;
	}
	else {
		cout << "请输入您要删除的职工号:";
		int id;
		cin >> id;

		int index = this->IsExist(id);

		if (index != -1) {
			// 数据前移
			for (int i = index; i < this->EmpNum_ - 1; i++) {
				this->EmpArray_[i] = this->EmpArray_[i + 1];
			}
			// 更新数组元素
			this->EmpNum_--;
			// 数据同步到文件中
			this->Save();
			cout << "删除成功!" << endl;

			system("pause");
			system("cls");
		}
		else {
			cout << "删除失败,未找到该职工!" << endl;
		}
	}
}

第五步:在 职工管理系统.cpp 绑定删除职工功能

#include <iostream>
using namespace std;
#include "workerManager.h"
#include "employee.h"
#include "manager.h"
#include "boss.h"

int main() {

	WorkerManager wm;
	int choice = 0; // 分支选择
	while (true) {
		// 显示菜单
		wm.Show_Menu();
		cout << "请输入您的选择:";
		cin >> choice;

		// 选择语句
		switch (choice) {
		case 0: // 退出系统
			wm.exitSystem();
			break;
		case 1: // 添加职工
			wm.Add_Emp();
			break;
		case 2: // 显示职工
			wm.Show_Emp();
			break;
		case 3: // 删除职工
			wm.Del_Emp();
			break;
		case 4: // 修改职工
			break;
		case 5: // 查找职工
			break;
		case 6: // 排序职工
			break;
		case 7: // 清空文件
			break;
		default:
			system("cls"); // 清屏
			break;
		}
	}

	system("pause");
	return 0;
}

实现修改职工功能

第一步:在 workerManager.h 完成函数声明 void Mod_Emp();

class WorkerManager {
	// 修改职工
	void Mod_Emp();
}

第二步:在 workerManager.cpp 实现函数功能

void WorkerManager::Mod_Emp() {
	if (this->FileIsEmpty_) {
		cout << "文件不存在或为空!" << endl;
	}
	else {
		cout << "请输入要修改职工的编号:";
		
		int id;
		cin >> id;

		int ret = this->IsExist(id);

		if (ret != -1) {
			delete this->EmpArray_[ret];

			int newId = 0;
			string newName = "";
			int newDId = 0;

			cout << "查到:" << id << " 号职工,请输入新职工号:";
			cin >> newId;
			cout << "请输入新姓名:";
			cin >> newName;
			cout << "请输入新岗位:" << endl;
			cout << "1. 普通职工" << endl;
			cout << "2. 经理" << endl;
			cout << "3. 老板" << endl;
			cin >> newDId;

			Worker *worker = NULL;
			switch (newDId) {
			case 1:
				worker = new Employee(newId, newName, newDId);
				break;
			case 2:
				worker = new Manager(newId, newName, newDId);
				break;
			case 3:
				worker = new Boss(newId, newName, newDId);
				break;
			default:
				break;
			}

			// 更改数据到数组中
			this->EmpArray_[ret] = worker;

			cout << "修改成功!" << this->EmpArray_[ret]->DeptId_ << endl;
		}
		else {
			cout << "修改失败!查无此人" << endl;
		}
	}
}

第三步:在 职工管理系统.cpp 绑定修改职工功能

#include <iostream>
using namespace std;
#include "workerManager.h"
#include "employee.h"
#include "manager.h"
#include "boss.h"

int main() {

	WorkerManager wm;
	int choice = 0; // 分支选择
	while (true) {
		// 显示菜单
		wm.Show_Menu();
		cout << "请输入您的选择:";
		cin >> choice;

		// 选择语句
		switch (choice) {
		case 0: // 退出系统
			wm.exitSystem();
			break;
		case 1: // 添加职工
			wm.Add_Emp();
			break;
		case 2: // 显示职工
			wm.Show_Emp();
			break;
		case 3: // 删除职工
			wm.Del_Emp();
			break;
		case 4: // 修改职工
			wm.Mod_Emp();
			break;
		case 5: // 查找职工
			break;
		case 6: // 排序职工
			break;
		case 7: // 清空文件
			break;
		default:
			system("cls"); // 清屏
			break;
		}
	}

	system("pause");
	return 0;
}

实现查找职工功能

功能描述:提供二种查找方法(按职工编号和按职工姓名)

具体步骤

第一步:在 workerManager.h 声明函数 void Find_Emp();

class WorkerManager {
	// 查找职工
	void Find_Emp();
}

第二步:在 workerManager.cpp 实现函数功能

void WorkerManager::Find_Emp() {
	if (this->FileIsEmpty_) {
		cout << "文件不存在或文件为空!" << endl;
	}
	else {
		cout << "请输入查找的方式:";
		cout << "1. 按职工编号查找";
		cout << "   2. 按姓名查找" << endl;

		int select = 0;
		cin >> select;

		if (select == 1) {
			int id;
			cout << "请输入查找的职工编号:";
			cin >> id;

			int ret = this->IsExist(id);
			if (ret != -1) {
				cout << "查找成功!该职工信息如下" << endl;
				this->EmpArray_[ret]->showInfo();
			}
			else {
				cout << "查找失败!查无此人" << endl;
			}
		}
		else if(select == 2) {
			string name;
			cout << "请输入查找的姓名:";
			cin >> name;

			bool flag = false;
			for (int i = 0; i < this->EmpNum_; i++) {
				if (this->EmpArray_[i]->Name_ == name) {
					cout << "查找成功!该职工信息如下" << endl;
					this->EmpArray_[i]->showInfo();
					flag = true;
				}
			}
			if (flag == false) {
				cout << "查找失败!查无此人" << endl;
			}
		}
	}

	system("pause");
	system("cls");
}

第三步:在 职工管理系统.cpp 绑定查询职工功能

#include <iostream>
using namespace std;
#include "workerManager.h"
#include "employee.h"
#include "manager.h"
#include "boss.h"

int main() {

	WorkerManager wm;
	int choice = 0; // 分支选择
	while (true) {
		// 显示菜单
		wm.Show_Menu();
		cout << "请输入您的选择:";
		cin >> choice;

		// 选择语句
		switch (choice) {
		case 0: // 退出系统
			wm.exitSystem();
			break;
		case 1: // 添加职工
			wm.Add_Emp();
			break;
		case 2: // 显示职工
			wm.Show_Emp();
			break;
		case 3: // 删除职工
			wm.Del_Emp();
			break;
		case 4: // 修改职工
			wm.Mod_Emp();
			break;
		case 5: // 查找职工
			wm.Find_Emp();
			break;
		case 6: // 排序职工
			break;
		case 7: // 清空文件
			break;
		default:
			system("cls"); // 清屏
			break;
		}
	}

	system("pause");
	return 0;
}

实现职工排序功能

第一步:在 workerManager.h 声明函数 void Sort_Emp();

class WorkerManager {
	// 排序职工
	void Sort_Emp();
}

第二步:在 workerManager.cpp 中实现函数功能

void WorkerManager::Sort_Emp() {
	if (this->FileIsEmpty_) {
		cout << "文件不存在或内容为空" << endl;
	}
	else {
		cout << "请选择排序方式:";
		cout << "1. 按职工号升序排序";
		cout << " 2. 按职工号降序排序" << endl;
		
		int select = 0;
		cin >> select;

		for (int i = 0; i < this->EmpNum_; i++) {
			int minOrMax = i; // 判断开始认定的最小值或最大值
			
			for (int j = i + 1; j < this->EmpNum_; j++) {
				if (select == 1) { // 升序
					if (this->EmpArray_[minOrMax]->Id_ > this->EmpArray_[j]->Id_) {
						minOrMax = j;
					}
				}
				else { // 降序
					if (this->EmpArray_[minOrMax]->Id_ < this->EmpArray_[j]->Id_) {
						minOrMax = j;
					}
				}
			}

			if (i != minOrMax) {
				Worker *temp = this->EmpArray_[i];
				this->EmpArray_[i] = this->EmpArray_[minOrMax];
				this->EmpArray_[minOrMax] = temp;
			}
		}
	}

	// 保存文件到文本
	this->Save();

	system("pause");
	system("cls");
}

第三步:在 职工管理系统.cpp 绑定排序职工功能

#include <iostream>
using namespace std;
#include "workerManager.h"
#include "employee.h"
#include "manager.h"
#include "boss.h"

int main() {

	WorkerManager wm;
	int choice = 0; // 分支选择
	while (true) {
		// 显示菜单
		wm.Show_Menu();
		cout << "请输入您的选择:";
		cin >> choice;

		// 选择语句
		switch (choice) {
		case 0: // 退出系统
			wm.exitSystem();
			break;
		case 1: // 添加职工
			wm.Add_Emp();
			break;
		case 2: // 显示职工
			wm.Show_Emp();
			break;
		case 3: // 删除职工
			wm.Del_Emp();
			break;
		case 4: // 修改职工
			wm.Mod_Emp();
			break;
		case 5: // 查找职工
			wm.Find_Emp();
			break;
		case 6: // 排序职工
			wm.Sort_Emp();
			break;
		case 7: // 清空文件
			break;
		default:
			system("cls"); // 清屏
			break;
		}
	}

	system("pause");
	return 0;
}

实现清空功能

第一步:在 workerManager.h 声明函数 void Clean_File();

class WorkerManager {
	// 清空数据
	void Clean_File();
}

第二步:在 workerManager.cpp 实现此函数

void WorkerManager::Clean_File() {
	cout << "确认清空?" << endl;
	cout << "1. 确认" << endl;
	cout << "2. 返回" << endl;

	int select = 0;
	cin >> select;

	if (select == 1) {
		// 打开模式 ios::trunc 如果存在则删除文件重新创建
		ofstream ofs;
		ofs.open(FILENAME, ios::trunc);
		ofs.close();

		if (this->EmpArray_ != NULL) {
			for (int i = 0; i < this->EmpNum_; i++) {
				if (this->EmpArray_[i] != NULL) {
					delete this->EmpArray_[i];
				}
			}

			this->EmpNum_ = 0;
			delete[]this->EmpArray_;
			this->EmpArray_ = NULL;
			this->FileIsEmpty_ = true;
		}

		cout << "清空成功!" << endl;
	}
	
	system("pause");
	system("cls");
}

第三步:在 职工管理系统.cpp 绑定清空职工功能

#include <iostream>
using namespace std;
#include "workerManager.h"
#include "employee.h"
#include "manager.h"
#include "boss.h"

int main() {

	WorkerManager wm;
	int choice = 0; // 分支选择
	while (true) {
		// 显示菜单
		wm.Show_Menu();
		cout << "请输入您的选择:";
		cin >> choice;

		// 选择语句
		switch (choice) {
		case 0: // 退出系统
			wm.exitSystem();
			break;
		case 1: // 添加职工
			wm.Add_Emp();
			break;
		case 2: // 显示职工
			wm.Show_Emp();
			break;
		case 3: // 删除职工
			wm.Del_Emp();
			break;
		case 4: // 修改职工
			wm.Mod_Emp();
			break;
		case 5: // 查找职工
			wm.Find_Emp();
			break;
		case 6: // 排序职工
			wm.Sort_Emp();
			break;
		case 7: // 清空文件
			wm.Clean_File();
			break;
		default:
			system("cls"); // 清屏
			break;
		}
	}

	system("pause");
	return 0;
}

源文件

1. 职工管理系统.cpp

#include <iostream>
using namespace std;
#include "workerManager.h"
#include "employee.h"
#include "manager.h"
#include "boss.h"

int main() {

	WorkerManager wm;
	int choice = 0; // 分支选择
	while (true) {
		// 显示菜单
		wm.Show_Menu();
		cout << "请输入您的选择:";
		cin >> choice;

		// 选择语句
		switch (choice) {
		case 0: // 退出系统
			wm.exitSystem();
			break;
		case 1: // 添加职工
			wm.Add_Emp();
			break;
		case 2: // 显示职工
			wm.Show_Emp();
			break;
		case 3: // 删除职工
			wm.Del_Emp();
			break;
		case 4: // 修改职工
			wm.Mod_Emp();
			break;
		case 5: // 查找职工
			wm.Find_Emp();
			break;
		case 6: // 排序职工
			wm.Sort_Emp();
			break;
		case 7: // 清空文件
			wm.Clean_File();
			break;
		default:
			system("cls"); // 清屏
			break;
		}
	}

	system("pause");
	return 0;
}

2. workerManager.h

#pragma once // 防止头文件重复包含
#include <iostream>
using namespace std;
#include "worker.h"
#include "employee.h"
#include "manager.h"
#include "boss.h"
#include <fstream>
#define FILENAME "EmpFile.txt"

class WorkerManager {
public:
	// 构造函数
	WorkerManager();
	// 显示菜单
	void Show_Menu();
	
	// 记录文件中人的数量
	int EmpNum_;
	// 员工数组的指针
	Worker ** EmpArray_;
	// 增加成员
	void Add_Emp();
	// 保存文件
	void Save();
	// 标志文件是否为空
	bool FileIsEmpty_;
	// 获取职工数目
	int get_EmpNum();
	// 初始化员工
	void init_Emp();
	// 显示职工
	void Show_Emp();
	// 删除职工
	void Del_Emp();
	// 判断职工是否存在
	int IsExist(int id);
	// 修改职工
	void Mod_Emp();
	// 查找职工
	void Find_Emp();
	// 排序职工
	void Sort_Emp();
	// 清空数据
	void Clean_File();
	
	// 退出系统
	void exitSystem();
	// 析构函数
	~WorkerManager();
};

3. workerManager.cpp

#include "workerManager.h"

WorkerManager::WorkerManager() {
	ifstream ifs; // 流对象
	ifs.open(FILENAME, ios::in);

	// 1. 文件不存在情况
	if (!ifs.is_open()) {
		// cout << "文件不存在" << endl; // 测试代码
		// 初始化人数
		this->EmpNum_ = 0;
		// 初始化文件为空标志
		this->FileIsEmpty_ = true;
		// 初始化数组指针
		this->EmpArray_ = NULL;
		ifs.close(); // 关闭文件
		return;
	}

	// 2. 文件存在并且没有记录
	char ch;
	ifs >> ch;
	if (ifs.eof()) {
		// cout << "文件为空!" << endl; // 测试代码
		this->EmpNum_ = 0;
		this->FileIsEmpty_ = true;
		this->EmpArray_ = NULL;
		ifs.close(); // 关闭文件
		return;
	}

	// 3. 文件存在且有记录
	int num = this->get_EmpNum();
	// cout << "职工个数为:" << num << endl; // 测试代码
	this->EmpNum_ = num; // 更新成员属性
	this->EmpArray_ = new Worker *[this->EmpNum_];
	// 初始化职工
	this->init_Emp();
}

void WorkerManager::Show_Menu() {
	cout << "*************************************" << endl;
	cout << "******** 欢迎使用职工管理系统! *****" << endl;
	cout << "*********  0.退出管理系统  **********" << endl;
	cout << "*********  1.增加职工信息  **********" << endl;
	cout << "*********  2.显示职工信息  **********" << endl;
	cout << "*********  3.删除职工信息  **********" << endl;
	cout << "*********  4.修改职工信息  **********" << endl;
	cout << "*********  5.查找职工信息  **********" << endl;
	cout << "*********  6.按照编号排序  **********" << endl;
	cout << "*********  7.清空所有文档  **********" << endl;
	cout << "*************************************" << endl;
}

void WorkerManager::Add_Emp() {
	cout << "请输入增加职工数量:";
	int addNum = 0;
	cin >> addNum;

	if (addNum > 0) {
		// 计算新空间大小
		int newSize = this->EmpNum_ + addNum;
		// 开辟新空间
		Worker ** newSpace = new Worker*[newSize];
		// 将原空间下数据存放到新空间下
		if (this->EmpArray_ != NULL) {
			for (int i = 0; i < this->EmpNum_; i++) {
				newSpace[i] = this->EmpArray_[i];
			}
		}
		// 输入并添加新数据
		for (int i = 0; i < addNum; i++) {
			int id;
			string name;
			int dId;

			cout << "请输入第 " << i + 1 << " 个新职工编号:";
			cin >> id;
			cout << "请输入第 " << i + 1 << " 个新职工姓名:";
			cin >> name;
			
			cout << "请选择新职工的岗位:" << endl;
			cout << "1. 普通职工" << endl;
			cout << "2. 经理" << endl;
			cout << "3. 老板" << endl;
			cin >> dId;

			Worker * worker = NULL;
			switch (dId) {
			case 1:
				worker = new Employee(id, name, dId);
				break;
			case 2:
				worker = new Manager(id, name, dId);
				break;
			case 3:
				worker = new Boss(id, name, dId);
				break;
			}
			// 添加新数据
			newSpace[this->EmpNum_ + i] = worker;
		}

		// 释放原有空间
		delete[]this->EmpArray_;
		// 更改新空间的指向
		this->EmpArray_ = newSpace;
		// 更新职工数目
		this->EmpNum_ = newSize;
		// 提示信息
		cout << "成功添加 " << addNum << " 名新职工!" << endl;
		this->Save();
	}
	else {
		cout << "输入有误!" << endl;
	}

	system("pause");
	system("cls");
}

void WorkerManager::Save() {
	ofstream ofs; // 流对象
	ofs.open(FILENAME, ios::out); // 写入数据

	for (int i = 0; i < this->EmpNum_; i++) {
		ofs << this->EmpArray_[i]->Id_ << " "
			<< this->EmpArray_[i]->Name_ << " "
			<< this->EmpArray_[i]->DeptId_ << " " << endl;
	}

	ofs.close(); // 关闭文件
}

int WorkerManager::get_EmpNum() {
	ifstream ifs;
	ifs.open(FILENAME, ios::in);

	int id;
	string name;
	int dId;

	int num = 0;

	while (ifs >> id && ifs >> name && ifs >> dId) {
		// 记录人数
		num++;
	}

	ifs.close();
	return num;
}

void WorkerManager::init_Emp() {
	ifstream ifs;
	ifs.open(FILENAME, ios::in);

	int id;
	string name;
	int dId;

	int index = 0;
	while (ifs >> id && ifs >> name && ifs >> dId) {
		Worker *worker = NULL;
		// 根据不同部门的 Id 创建不同对象
		if (dId == 1) {
			worker = new Employee(id, name, dId);
		}
		else if (dId == 2) {
			worker = new Manager(id, name, dId);
		}
		else {
			worker = new Boss(id, name, dId);
		}

		// 存放在数组中
		this->EmpArray_[index] = worker;
		index++;
	}
}

void WorkerManager::Show_Emp() {
	if (this->FileIsEmpty_) {
		cout << "文件不存在或文件为空!" << endl;
	}
	else {
		for (int i = 0; i < this->EmpNum_; i++) {
			// 利用多态调用接口
			this->EmpArray_[i]->showInfo();
		}
	}

	system("pause");
	system("cls");
}

int WorkerManager::IsExist(int id) {
	int index = -1;

	for (int i = 0; i < this->EmpNum_; i++) {
		if (this->EmpArray_[i]->Id_ == id) {
			index = i;
			break;
		}
	}
	return index;
}

void WorkerManager::Del_Emp() {
	if (this->FileIsEmpty_) {
		cout << "文件为空或者不存在!" << endl;
	}
	else {
		cout << "请输入您要删除的职工号:";
		int id;
		cin >> id;

		int index = this->IsExist(id);

		if (index != -1) {
			// 数据前移
			for (int i = index; i < this->EmpNum_ - 1; i++) {
				this->EmpArray_[i] = this->EmpArray_[i + 1];
			}
			// 更新数组元素
			this->EmpNum_--;
			// 数据同步到文件中
			this->Save();
			cout << "删除成功!" << endl;

			system("pause");
			system("cls");
		}
		else {
			cout << "删除失败,未找到该职工!" << endl;
		}
	}
}

void WorkerManager::Mod_Emp() {
	if (this->FileIsEmpty_) {
		cout << "文件不存在或为空!" << endl;
	}
	else {
		cout << "请输入要修改职工的编号:";
		
		int id;
		cin >> id;

		int ret = this->IsExist(id);

		if (ret != -1) {
			delete this->EmpArray_[ret];

			int newId = 0;
			string newName = "";
			int newDId = 0;

			cout << "查到:" << id << " 号职工,请输入新职工号:";
			cin >> newId;
			cout << "请输入新姓名:";
			cin >> newName;
			cout << "请输入新岗位:" << endl;
			cout << "1. 普通职工" << endl;
			cout << "2. 经理" << endl;
			cout << "3. 老板" << endl;
			cin >> newDId;

			Worker *worker = NULL;
			switch (newDId) {
			case 1:
				worker = new Employee(newId, newName, newDId);
				break;
			case 2:
				worker = new Manager(newId, newName, newDId);
				break;
			case 3:
				worker = new Boss(newId, newName, newDId);
				break;
			default:
				break;
			}

			// 更改数据到数组中
			this->EmpArray_[ret] = worker;
			// 保存文件
			this->Save();

			cout << "修改成功!" << this->EmpArray_[ret]->DeptId_ << endl;
		}
		else {
			cout << "修改失败!查无此人" << endl;
		}
	}

	system("pause");
	system("cls");
}

void WorkerManager::Find_Emp() {
	if (this->FileIsEmpty_) {
		cout << "文件不存在或文件为空!" << endl;
	}
	else {
		cout << "请输入查找的方式:";
		cout << "1. 按职工编号查找";
		cout << "   2. 按姓名查找" << endl;

		int select = 0;
		cin >> select;

		if (select == 1) {
			int id;
			cout << "请输入查找的职工编号:";
			cin >> id;

			int ret = this->IsExist(id);
			if (ret != -1) {
				cout << "查找成功!该职工信息如下" << endl;
				this->EmpArray_[ret]->showInfo();
			}
			else {
				cout << "查找失败!查无此人" << endl;
			}
		}
		else if(select == 2) {
			string name;
			cout << "请输入查找的姓名:";
			cin >> name;

			bool flag = false;
			for (int i = 0; i < this->EmpNum_; i++) {
				if (this->EmpArray_[i]->Name_ == name) {
					cout << "查找成功!该职工信息如下" << endl;
					this->EmpArray_[i]->showInfo();
					flag = true;
				}
			}
			if (flag == false) {
				cout << "查找失败!查无此人" << endl;
			}
		}
	}

	system("pause");
	system("cls");
}

void WorkerManager::Sort_Emp() {
	if (this->FileIsEmpty_) {
		cout << "文件不存在或内容为空" << endl;
	}
	else {
		cout << "请选择排序方式:";
		cout << "1. 按职工号升序排序";
		cout << " 2. 按职工号降序排序" << endl;
		
		int select = 0;
		cin >> select;

		for (int i = 0; i < this->EmpNum_; i++) {
			int minOrMax = i; // 判断开始认定的最小值或最大值
			
			for (int j = i + 1; j < this->EmpNum_; j++) {
				if (select == 1) { // 升序
					if (this->EmpArray_[minOrMax]->Id_ > this->EmpArray_[j]->Id_) {
						minOrMax = j;
					}
				}
				else { // 降序
					if (this->EmpArray_[minOrMax]->Id_ < this->EmpArray_[j]->Id_) {
						minOrMax = j;
					}
				}
			}

			if (i != minOrMax) {
				Worker *temp = this->EmpArray_[i];
				this->EmpArray_[i] = this->EmpArray_[minOrMax];
				this->EmpArray_[minOrMax] = temp;
			}
		}
	}

	// 保存文件到文本
	this->Save();

	system("pause");
	system("cls");
}

void WorkerManager::Clean_File() {
	cout << "确认清空?" << endl;
	cout << "1. 确认" << endl;
	cout << "2. 返回" << endl;

	int select = 0;
	cin >> select;

	if (select == 1) {
		// 打开模式 ios::trunc 如果存在则删除文件重新创建
		ofstream ofs;
		ofs.open(FILENAME, ios::trunc);
		ofs.close();

		if (this->EmpArray_ != NULL) {
			for (int i = 0; i < this->EmpNum_; i++) {
				if (this->EmpArray_[i] != NULL) {
					delete this->EmpArray_[i];
				}
			}

			this->EmpNum_ = 0;
			delete[]this->EmpArray_;
			this->EmpArray_ = NULL;
			this->FileIsEmpty_ = true;
		}

		cout << "清空成功!" << endl;
	}
	
	system("pause");
	system("cls");
}

void WorkerManager::exitSystem() {
	cout << "欢迎下次使用!" << endl;
	system("pause");
	exit(0); // 程序退出
}

WorkerManager::~WorkerManager() {

}

4. worker.h

#pragma once
#include <iostream>
#include <string>
using namespace std;

// 职工抽象类
class Worker {
public:
	// 纯虚函数
	// 显示个人信息
	virtual void showInfo() = 0;
	// 获取岗位信息
	virtual string getDeptName() = 0;

public:
	int Id_; // 职工编号
	string Name_; // 职工姓名
	int DeptId_; // 职工所在部门编号
};

5. employee.h

#pragma once
#include <iostream>
#include "worker.h"

// 员工类
class Employee :public Worker{
public:
	// 构造函数
	Employee(int id, string name, int dId);
	// 显示个人信息
	virtual void showInfo();
	// 获取职工岗位名称
	virtual string getDeptName();
};

6. employee.cpp

#include "employee.h"

Employee::Employee(int id, string name, int dId) {
	this->Id_ = id;
	this->Name_ = name;
	this->DeptId_ = dId;
}

void Employee::showInfo() {
	cout << "职工编号:" << this->Id_
		<< "\t职工姓名:" << this->Name_
		<< "\t岗位:" << this->DeptId_
		<< "\t岗位职责:完成经理交给的问题" << endl;
}

string Employee::getDeptName() {
	return string("员工");
}

7. manager.h

#pragma once
#include <iostream>
#include "worker.h"

// 经理类
class Manager :public Worker {
public:
	// 构造函数
	Manager(int id, string name, int dId);
	// 显示个人信息
	virtual void showInfo();
	// 获取职工岗位名称
	virtual string getDeptName();
};

8. manager.cpp

#include "manager.h"

Manager::Manager(int id, string name, int dId) {
	this->Id_ = id;
	this->Name_ = name;
	this->DeptId_ = dId;
}

void Manager::showInfo() {
	cout << "职工编号:" << this->Id_
		<< "\t职工姓名:" << this->Name_
		<< "\t岗位:" << this->DeptId_
		<< "\t岗位职责:完成老板交给的问题" << endl;
}

string Manager::getDeptName() {
	return string("经理");
}

9. boss.h

#pragma once
#include <iostream>
#include "worker.h"

// 老板类
class Boss :public Worker {
public:
	// 构造函数
	Boss(int id, string name, int dId);
	// 显示个人信息
	virtual void showInfo();
	// 获取职工岗位名称
	virtual string getDeptName();
};

10. boss.cpp

#include "boss.h"

Boss::Boss(int id, string name, int dId) {
	this->Id_ = id;
	this->Name_ = name;
	this->DeptId_ = dId;
}

void Boss::showInfo() {
	cout << "职工编号:" << this->Id_
		<< "\t职工姓名:" << this->Name_
		<< "\t岗位:" << this->DeptId_
		<< "\t岗位职责:管理公司所有事务" << endl;
}

string Boss::getDeptName() {
	return string("员工");
}
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是我来晚了!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值