第二个小项目--职工管理系统
只完成一半
先记录一下
答题和通讯录管理系统差不多,不同的是使用到 了类的多态,使用文件存储。还有一些技巧性,规范性的东西。
根据职责不同,不同职责的人继承一个抽象类。这个反而不重要。
定义一个Manage类,实现核心功能,增删改查等。重要。
由于涉及到了数据的保存,所以让我长了一个很大的见识就是将 判断文件是否存在,文件是否为空,文件中有多少个人的数据(int get_num),读取文件的数据到内存(void init) 这些功能(当然这些功能需要细化到几个函数来实现) 全都放在了类的构造函数中,然后使用几个变量或布尔值记录一下状态,很6。这可能就是好的架构吧。
有一个变量是 Worker ** p = new Worker*[size],指向指针数组的指针,用这个指向指针数组的指针来管理 每一个人。数组中为每一个人实例化的指针,通过对p的操作,通过多态,就可以将操作精细到每个人,目前小白的角度,觉的很6。比如说
void System::ShowPeople() { if (!this->FileisExit && this->FileisEmpty) { cout << "数据库不存在!!!" << endl; } else { if (this->FileisExit && this->FileisEmpty) { cout << "数据库为空" << endl; } else { for (int i = 0; i < this->DbFileNum; i++) { this->m_person[i]->ShowJob(); } } } }
增,删,改,查 都会与这个 p指针 打交道。
总结下坑
1 switch 我踩了两个坑。
switch (x) { cout << "xyz" << endl; case 1: break; case 2: break; default: break; }
一个是xyz不会打印, 根据x直接跳到 符合的case中,执行相应的逻辑
二是 case一定要带break,不带break,会继续往下执行,!!
2 判断 文件为空
读取一个字符,看到没到结尾。
char ch; ifs >> ch; if (ifs.eof()) { this->FileisExit = true; this->FileisEmpty = true; this->DbFileNum = 0; this->m_person = NULL; }
3 知道每一行的固定格式,读取全部内容
int System::GetDbNum() { ifstream ifs(filename, ios::in); int id; int did; string name; int num = 0; while (ifs>>id && ifs >> did && ifs>>name) { num++; } ifs.close(); return num; }
4 init 从文件中 初始化 内存中,变量保存。这就是前面我说的在构造函数中实现的一个功能。666
void System::init() { int id; int did; string name; ifstream ifs(filename, ios::in); int index = 0; while (ifs >> id && ifs >> did && ifs>>name) { Person* p = NULL; switch (did) { case 1: { p = new Boss(id, did, name); this->m_person[index] = p; index++; break; } case 2: { p = new Employee(id, did, name); this->m_person[index] = p; index++; break; } } } ifs.close(); }
构造函数中实现的另一个功能,获取文件中有多少个人。
int System::GetDbNum() { ifstream ifs(filename, ios::in); int id; int did; string name; int num = 0; while (ifs>>id && ifs >> did && ifs>>name) { num++; } ifs.close(); return num; }
5 析构函数
对手动开辟的空间释放 分三步
判断指针p是不是空。
如果不为空,delete 指针p
指针p = NULL。赋值
System::~System() { cout << "析构函数 " << endl; if (this->m_person != NULL) { for (int i = 0; i < this->DbFileNum; i++) if (this->m_person[i] != NULL) { delete this->m_person[i]; } delete[] this->m_person; this->m_person = NULL; } }
6 构造函数
System::System() { ifstream ifs(filename, ios::in); if (!ifs.is_open()) { this->FileisExit = false; this->FileisEmpty = true; this->DbFileNum = 0; this->m_person = NULL; } else { char ch; ifs >> ch; if (ifs.eof()) { this->FileisExit = true; this->FileisEmpty = true; this->DbFileNum = 0; this->m_person = NULL; } else { this->FileisExit = true; this->FileisEmpty = false; this->DbFileNum = this->GetDbNum(); this->m_person = new Person * [this->DbFileNum]; this->init(); } } ifs.close(); }
7 添加人员
void System::AddPeople() { int newsize = this->DbFileNum + 1; cout << "newsize: " << newsize << endl; Person** newspace = new Person * [newsize]; for (int i = 0; i < this->DbFileNum; i++) { newspace[i] = this->m_person[i]; } int cho; cout << "请选择创建的人员 1 : boss 2 : employerr " << endl; cin >> cho; int id; cout << "请输入 id : " << endl; cin >> id; int did; cout << "请输入职业 1 :boss 2 :employee " << endl; cin >> did; string name; cout << "请输入姓名 : " << endl; cin >> name; cout << "DbFileNum: " << this->DbFileNum << endl; switch (cho) { case 1: { Person* p = new Boss(id, did, name); cout << "1" << endl; p->ShowJob(); newspace[newsize - 1] = p; break; } case 2: { Person* p = new Employee(id, did, name); cout << " this->DbFileNum: "<< this->DbFileNum << "newsize: " << newsize << endl; p->ShowJob(); newspace[newsize-1] = p; cout << "33" << endl; break; } } this->DbFileNum = newsize; delete[] this->m_person; this->m_person = newspace; this->FileisExit = false; this->save(); }
后记
在散步的时候,想了下C++ 和 python的区别。
现在感受到了python是多么的边界,变量不用声明类型,然后列表,是个无比强大的工具。什么类型都能往里放,还能append,简直牛逼。
C++中,我觉的很多时间,很多代码就是操作内存。
手动的创建数组
Person** newspace = new Person * [newsize];
手动的赋值,Person 一个一个的赋值
for (int i = 0; i < this->DbFileNum; i++)
{ newspace[i] = this->m_person[i];
}
手动的删除
delete[] this->m_person;
手动的重新指向
this->m_person = newspace;
从这个角度上来看,代码量确实是很多的