?? h1.h
字號:
#include<iostream>
#include<cstdlib>
#include<Record.h>
using namespace std;
struct Record
{
string number; // 學號(中間不能有空格)
string name; // 姓名(中間可以有空格)
string gender; // 性別(中間無空格)
float score[NUM_SUBJECT]; // 分別為該學生5門課的成績
float sum; // 總分
float average; // 平均分
int index; // 名次
bool toBeDeleted; // 做是否刪除的標記
Record() {toBeDeleted = false;}
};
class RecordVec : public vector<Record*>{
friend ostream& operator<< (ostream& os, const RecordVec& c_rl);
friend istream& operator>> (istream& is, RecordVec& rl);
public: // 銷毀數組中記錄的所有Record所占用的內存空間,
//并且清空數組存儲的記錄
// 該函數覆蓋了基類中的同名函數
void clear(); // 銷毀指定的記錄,然后從數組中將其刪除
// 該函數覆蓋了基類中的同名函數
iterator erase(iterator where);
~RecordVec();
};
class StuInfoVec
{
protected:
RecordVec recVec;
public:
typedef vector<Record>::iterator Iterator;
//添加新的學生的記錄
virtual void addRecord(Record* rec);
//刪除有"待刪除"標志的記錄
virtual int removePerform();
//尋找一個學生記錄
virtual Iterator findRecord(const string& patten, int type, Iterator form);
//將學生信息保存到輸出流中
virtual void saveRecords(ostream& os);
//從輸入流中讀入數據,并追加到當前學生信息記錄的末尾
virtual int loadRecords(istream& in);
virtual ~StuInfoVec();
//獲得記錄的學生數量
const int size() const {return (int)recVec.size();}
//是否無學生信息
const bool empty() const {return recVec.empty();}
//清空學生信息
virtual void clear(){recVec.clear();}
//獲得第一條記錄
Iterator first(){return recVec.begin();}
//獲得超過最后一條記錄之后的一個迭代器
Iterator pastEnd(){return recVec.end();}
};
該類是處理學信息記錄的底層類,針對增加記錄、刪除記錄、查詢記錄一級保存和讀取記錄等操作進行與底層數據結構相關的處理,該類不涉及與用戶界面或用戶交互相關的操作。
該類以"包含"(has a)關系持有一個RecordVec類的對象recVec,作為保護型數據成員,這是存取記錄的底層數據結構。
StuInfoVec類中定義的一些成員函數直接使用了RecordVec類的成員函數,沒有增加太多的功能,如addRecord()函數只是調用了RecordVec類繼承子基類的push_back()函數,saveRecord()函數只是調用了RecordVec重載的輸出操作符。
需要特別解釋的是以下三個函數:
1) findRecord()成員函數。它用于從已有的學生信息記錄中尋找一個符合條件的記錄,并返回指向該記錄的迭代器(iterator)。該函數將從給定的iterator開始,按遞增的順序依次考察每一記錄,直到找到符合條件的記錄或者到達記錄的末尾。Iterator迭代遍歷記錄時采用如下的代碼:
Iterator it;
iterator it_end = recVec.end();
for(it = from; it != it_end; it++)
{
//對it進行操作
}
這里的form時迭代開始的位置,it_end時記錄的末尾,如要遍歷整個記錄并找出所有符合條件的記錄,form第一次可以使用recVec.begin()函數的返回值,之后每次取前一次運算后findRecord()函數所得返回值增1,直到findRecord()函數返回it_end為止。
另外由于存儲記錄的數據結構是vector,vector可以通過下標操作符[]以常量時間存取它的任一個元素,所以遍歷記錄的另外一種方式就是通過下標操作:
int nSize;
for(int i = 0; i < nSize; i++)
{
//對recVec[i]進行操作
}
2) removePerform()成員函數。用于從數組中真正刪除做了"待刪除"標志的記錄,并返回實際上刪除了的記錄數。
由于向量這種數據結構的特點,每刪除一個元素都必須將被刪除元素后面的所有元素前移一格,為了減少這種移動的次數,提高效率,故從向量的末尾開始逆向尋找每一個做了標記的記錄,調用recVec的erase()成員函數實際將其刪除。
由于記錄中有一個"名次"項,所以在刪除了記錄以后,為了保證名次的正確,必須更新剩余記錄的"名次"項,更新的方法是將剩余記錄名次排在被刪除記錄后面的記錄的名次減1。
3) loadRecords()成員函數。將寫在文件里的記錄讀取出來,追加在當前記錄的末尾,這是通過對recVec調用其重載的操作符>>實現的。但是如果追加前已經有了一部分記錄信息,則加入了新的記錄以后名次會被打亂,因此所有記錄的"名次"項都要進行調整。調整的方法是對每條記錄都計算總分大于它的人數ncount,而該記錄的名次便是ncount+1。
4. 類StuInfoManager
它的聲明如下:
class StuInfoManager
{
protected:
bool isModified;//學生信息是否已被修改還未保存
int toRemvNodes;//做了刪除標記的記錄數
public:
static char* subject_[];
public:
StuInfoManager();
virtual ~StuInfoManager();
//開始成績
virtual void start();
//菜單處理函數管理程序的用戶界面操作
virtual void handleMenu();
//顯示記錄
virtual void displayRecords();
//查詢記錄
virtual void queryRecord();
//添加記錄
virtual void addRecord();
//刪除記錄
virtual void removeRecord();
//標記刪除記錄
virtual void removeNote();
//修改記錄
virtual void modifyRecord();
//記錄排序
virtual void sortRecords();
//保存記錄
virtual void saveRecords();
//讀取記錄
virtual void loadRecords();
//結束程序
virtual void quit();
//清空當前記錄信息
virtual void clear();
//菜單選擇函數
char menuSelect();
//顯示表頭
void dispTable();
//顯示一條記錄的信息
void dispRecord();
//找出給定總分在所有記錄中的名次
int getIndex(float sum);
};
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -