<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
前言:
前面介紹到了C++的泛型程式設計,並實現了萬能容器,不過那使用的是陣列,今天呢咱帶大家實踐一下使用泛型技術,結合單連結串列實現一個職工管理系統。保證大家看完之後有所感悟。
所謂泛型就是型別不固定,只需修改少量程式碼就可以擴充套件為其他型別的應用,由於C++是一門靜態編譯型的語言,變數的型別都是事先編譯好的,如果不用泛型進行程式設計,一段程式碼始終就是那麼點作用。使用泛型程式設計後,可以很簡單的對其他型別進行擴充套件。泛型程式設計核心思想就是將資料型別設定為模板,第一次編譯是對模板進行編譯,第二次編譯會帶入人為傳的型別引數。前面文章有講函數模板與類別範本,忘記的小夥伴可以去看看。
單連結串列中的單代表一條,連結串列意思就是一個個節點連結起來的表結構。
其最典型的特徵就是節點只有一個指標域。並且該指標域指向下一節點的地址
①常規連結串列節點
class node { private: //資料域 string data1; string data2; //指標域 node* next; public: node() { } }
②泛型連結串列節點
其中T代表的是一種不確定的資料型別,data是一個T型別的物件,其作用類似於結構體儲存資料域的資訊,但是在c++中他必須用類實現,因為該資料型別要有屬於自己的屬性與方法。node* next
代表一個T型別的node指標,其本質還是node指標,只不過T的型別決定著node *指向的節點中的data的型別。
程式碼如下:
template<typename T> class node { private: //資料域 T data; //指標域 node<T>* next; public: node() { } }
常規連結串列類中需要包含一個頭指標,指向連結串列的頭結點,然後建立一個連結串列對其增刪改查泛型程式設計中的連結串列類,也要是一個連結串列類。實現型別的引數化,具體如下:
template<typename T> class link { private: //傳入型別的時候,先傳給link然後link會傳給node; node<T>* head; public: link() { } bool add(){ } bool del(){ }
泛型就是要將你寫的型別,像對待int string型別那樣對待。首先要進行的就是運運算元過載過載了運運算元你可以使用cin,cout直接對相應的物件進行輸入,輸出。可以直接使用=進行賦值。
具體實現如下:
class officer { //過載了標準輸入輸出流函數、檔案輸入輸出流函數(可以直接存檔案) friend ostream& operator<<(ostream& out, officer& obj); friend istream& operator>>(istream& in, officer& obj); friend ofstream& operator<<(ofstream& outfile, officer& obj);//--------輸出到檔案 friend ifstream& operator>>(ifstream& infile, officer& obj);//---------讀取檔案 private: string id_card; string name; string sex; int age; string post; int money; public://---------------------------------私有屬性管理方法 officer() { id_card = ""; name = ""; sex = ""; age = 0; post = ""; money = 0; } //拷貝建構函式結合賦值函數,直接進行賦值。 officer(officer& obj) { this->id_card = obj.getid(); this->name = obj.getname(); this->sex = obj.getsex(); this->age = obj.getage(); this->money = obj.getmoney(); this->post = obj.getpost(); } officer& operator=(officer& obj) { this->id_card = obj.getid(); this->name = obj.getname(); this->sex = obj.getsex(); this->age = obj.getage(); this->money = obj.getmoney(); this->post = obj.getpost(); return *this; } //查重時使用 bool operator==(officer& obj) { if (this->getid() == obj.getid() && this->getname() == obj.getname() && this->getsex() == obj.getsex() && this->getage() == obj.getage() && this->getpost() == obj.getpost() && this->getmoney() == obj.getmoney()) { return true; } return false; } bool operator!=(officer& obj) { if (this->getid() == obj.getid()) { return false; } return true; } //排序時使用,根據工資的高低。 bool operator>(officer& obj) { if (this->getmoney() > obj.getmoney()) { return true; } return false; } bool operator<(officer& obj) { if (this->getmoney() < obj.getmoney()) { return true; } return false; } void setpost(string post) { this->post = post; } void setmoney(int money) { this->money = money; } void setid(string id) { id_card = id; } void setname(string name) { this->name = name; } void setsex(string sex) { this->sex = sex; } void setage(int age) { this->age = age; } string getid() { return id_card; } string getname() { return name; } string getsex() { return sex; } int getage() { return age; } string getpost() { return post; } int getmoney() { return money; } };
泛型的連結串列類、節點類一般就是寫死的,做到換一個資料類還可以用的效果所以在泛型連結串列類中的提示性語句要有一定的泛化程度,不可以針對某種型別提示。
template<typename T> class link { private: node<T>* head; public: link() { string classname; ifstream infile; node<T>* p, * q; p = new node<T>; p->setnext(NULL); head = new node<T>; head->setnext(NULL); q = head; classname = head->GetClass(); classname.erase(remove(classname.begin(), classname.end(), '<'), classname.end()); classname.erase(remove(classname.begin(), classname.end(), '>'), classname.end()); //cout << classname << endl; infile.open(classname); while (infile >> p->opedata()) { q->setnext(p); q = q->getnext(); p = new node<T>; p->setnext(NULL); } delete p; infile.close(); } void addnode() {//-------------------------增 node<T>* p, * q; p = new node<T>; p->setnext(NULL); cout << "請輸入您要儲存的資料:" << endl; cin >> p->opedata(); q = head; for (; q->getnext() != NULL; q = q->getnext()) { if (q->getnext()->opedata() == p->opedata()) { cout << "您輸入的資料,已存在,不需要重複錄入" << endl; system("pause"); delete p; return; } } q->setnext(p); savelink(); cout << "儲存成功!" << endl; system("pause"); } void delnode() {//---------------------------刪 bool k = false; node<T>* p, * q, * r; p = new node<T>; p->setnext(NULL); cout << "請輸入您要刪除的資料" << endl; cin >> p->opedata(); q = head; for (; q->getnext() != NULL; q = q->getnext()) { if (q->getnext()->opedata() == p->opedata() && q->getnext()->getnext() != NULL) { r = q->getnext(); q->getnext() = q->getnext()->getnext(); delete r; k = true; break; } else if (q->getnext()->opedata() == p->opedata() && q->getnext()->getnext() == NULL) { r = q->getnext(); delete r; q->setnext(NULL); k = true; break; } } if (k == false) { cout << "沒有找到您要刪除的資料,請核實後再來!" << endl; } else if (k == true) { savelink(); cout << "刪除成功!" << endl; } delete p; system("pause"); return; } void altenode() {//-------------------------------改 int judgecin = 0; bool k = false; node<T>* p, * q, * r; p = new node<T>; p->setnext(NULL); cout << "請輸入您要改動的資料" << endl; judgecin = 1; cin >> p->opedata(); judgecin = 0; q = head; for (; q->getnext() != NULL; q = q->getnext()) { if (q->getnext()->opedata() == p->opedata()) { cout << "請輸入新的資料:" << endl; rewrite: cin >> p->opedata(); for (r = head; r->getnext() != NULL; r = r->getnext()) { if (r->getnext()->opedata() == p->opedata() && p->opedata() != q->getnext()->opedata()) { system("cls"); judgecin++; if (judgecin == 3) { cout << "您多次輸入資訊錯誤,請核實後再來,將要返回主選單" << endl; delete p; system("pause"); return; } cout << "請輸入您自己的身份資訊!或輸入新的身份證號" << endl; goto rewrite; } } q->getnext()->opedata() = p->opedata(); k = true; } } if (k == true) { savelink(); cout << "修改成功!" << endl; } else { cout << "修改失敗!沒有找到該資料!" << endl; } delete p; system("pause"); return; } void selnode() {//----------------------------------查 cout << "請輸入您要查詢的資料" << endl; bool k = false; node<T>* p, * q; p = new node<T>; p->setnext(NULL); cin >> p->opedata(); for (q = head; q->getnext() != NULL; q = q->getnext()) { if (q->getnext()->opedata() == p->opedata()) { k = true; cout << "您要查詢的資料如下!" << endl; cout << q->getnext()->opedata() << endl; //break; } } if (k == false) { cout << "沒有找到您要查詢的資料!抱歉" << endl; } system("pause"); return; } void printlink() {//------------------------------列印連結串列 node<T>* p; sortlink(); for (p = head; p->getnext() != NULL; p = p->getnext()) { cout << p->getnext()->opedata() << endl; } system("pause"); } void sortlink() {//-------------------------------排序 node<T>* p, * q; if (head->getnext() == NULL) { cout << "沒有資料,無需排序!" << endl; return; } if (head->getnext()->getnext() == NULL) { cout << "一組資料,無需排序!" << endl; return; } for (p = head->getnext(); p->getnext() != NULL; p = p->getnext()) { for (q = p->getnext(); q != NULL; q = q->getnext()) { if (q->opedata() > p->opedata()) { node<T> temp; temp = *q; *q = *p; *p = temp; temp.getnext() = q->getnext(); q->getnext() = p->getnext(); p->getnext() = temp.getnext(); } } } } void savelink() {//--------------------------------------存連結串列 ofstream outfile; string classname; node<T>* p; p = head; classname = head->GetClass(); classname.erase(remove(classname.begin(), classname.end(), '<'), classname.end()); classname.erase(remove(classname.begin(), classname.end(), '>'), classname.end()); outfile.open(classname); while (p->getnext() != NULL) { p = p->getnext(); outfile << p->opedata() << endl; } outfile.close(); } ~link() {//--------------------------------------------銷燬連結串列 node<T>* p; p = head->getnext(); while (p != NULL) { delete head; head = p; p = p->getnext(); } }// };
officer
型別換為int型別,程式依舊可以穩定的執行。char off_menu(); class officer; int mynum(string str) {//-----------------判斷字串是否全為數位 for (unsigned int i = 0; i < str.length(); i++) { if (!isdigit(str[i])) { return 1; } } return 0; } template<typename T> class node { private: T data; node<T>* next; public: node() { } void setnext(node<T>* p) { if (p != NULL) { next = new node<T>; next->data = p->opedata(); next->next = p->getnext(); } else next = p; } T& opedata() { return data; } node<T>*& getnext() { return next; } const char* GetClass() { return typeid(*this).name(); } }; template<typename T> class link { private: node<T>* head; public: link() { string classname; ifstream infile; node<T>* p, * q; p = new node<T>; p->setnext(NULL); head = new node<T>; head->setnext(NULL); q = head; classname = head->GetClass(); classname.erase(remove(classname.begin(), classname.end(), '<'), classname.end()); classname.erase(remove(classname.begin(), classname.end(), '>'), classname.end()); //cout << classname << endl; infile.open(classname); while (infile >> p->opedata()) { q->setnext(p); q = q->getnext(); p = new node<T>; p->setnext(NULL); } delete p; infile.close(); } void addnode() {//-------------------------增 node<T>* p, * q; p = new node<T>; p->setnext(NULL); cout << "請輸入您要儲存的資料:" << endl; cin >> p->opedata(); q = head; for (; q->getnext() != NULL; q = q->getnext()) { if (q->getnext()->opedata() == p->opedata()) { cout << "您輸入的資料,已存在,不需要重複錄入" << endl; system("pause"); delete p; return; } } q->setnext(p); savelink(); cout << "儲存成功!" << endl; system("pause"); } void delnode() {//---------------------------刪 bool k = false; node<T>* p, * q, * r; p = new node<T>; p->setnext(NULL); cout << "請輸入您要刪除的資料" << endl; cin >> p->opedata(); q = head; for (; q->getnext() != NULL; q = q->getnext()) { if (q->getnext()->opedata() == p->opedata() && q->getnext()->getnext() != NULL) { r = q->getnext(); q->getnext() = q->getnext()->getnext(); delete r; k = true; break; } else if (q->getnext()->opedata() == p->opedata() && q->getnext()->getnext() == NULL) { r = q->getnext(); delete r; q->setnext(NULL); k = true; break; } } if (k == false) { cout << "沒有找到您要刪除的資料,請核實後再來!" << endl; } else if (k == true) { savelink(); cout << "刪除成功!" << endl; } delete p; system("pause"); return; } void altenode() {//-------------------------------改 int judgecin = 0; bool k = false; node<T>* p, * q, * r; p = new node<T>; p->setnext(NULL); cout << "請輸入您要改動的資料" << endl; judgecin = 1; cin >> p->opedata(); judgecin = 0; q = head; for (; q->getnext() != NULL; q = q->getnext()) { if (q->getnext()->opedata() == p->opedata()) { cout << "請輸入新的資料:" << endl; rewrite: cin >> p->opedata(); for (r = head; r->getnext() != NULL; r = r->getnext()) { if (r->getnext()->opedata() == p->opedata() && p->opedata() != q->getnext()->opedata()) { system("cls"); judgecin++; if (judgecin == 3) { cout << "您多次輸入資訊錯誤,請核實後再來,將要返回主選單" << endl; delete p; system("pause"); return; } cout << "請輸入您自己的身份資訊!或輸入新的身份證號" << endl; goto rewrite; } } q->getnext()->opedata() = p->opedata(); k = true; } } if (k == true) { savelink(); cout << "修改成功!" << endl; } else { cout << "修改失敗!沒有找到該資料!" << endl; } delete p; system("pause"); return; } void selnode() {//----------------------------------查 cout << "請輸入您要查詢的資料" << endl; bool k = false; node<T>* p, * q; p = new node<T>; p->setnext(NULL); cin >> p->opedata(); for (q = head; q->getnext() != NULL; q = q->getnext()) { if (q->getnext()->opedata() == p->opedata()) { k = true; cout << "您要查詢的資料如下!" << endl; cout << q->getnext()->opedata() << endl; //break; } } if (k == false) { cout << "沒有找到您要查詢的資料!抱歉" << endl; } system("pause"); return; } void printlink() {//------------------------------列印連結串列 node<T>* p; sortlink(); for (p = head; p->getnext() != NULL; p = p->getnext()) { cout << p->getnext()->opedata() << endl; } system("pause"); } void sortlink() {//-------------------------------排序 node<T>* p, * q; if (head->getnext() == NULL) { cout << "沒有資料,無需排序!" << endl; return; } if (head->getnext()->getnext() == NULL) { cout << "一組資料,無需排序!" << endl; return; } for (p = head->getnext(); p->getnext() != NULL; p = p->getnext()) { for (q = p->getnext(); q != NULL; q = q->getnext()) { if (q->opedata() > p->opedata()) { node<T> temp; temp = *q; *q = *p; *p = temp; temp.getnext() = q->getnext(); q->getnext() = p->getnext(); p->getnext() = temp.getnext(); } } } } void savelink() {//--------------------------------------存連結串列 ofstream outfile; string classname; node<T>* p; p = head; classname = head->GetClass(); classname.erase(remove(classname.begin(), classname.end(), '<'), classname.end()); classname.erase(remove(classname.begin(), classname.end(), '>'), classname.end()); outfile.open(classname); while (p->getnext() != NULL) { p = p->getnext(); outfile << p->opedata() << endl; } outfile.close(); } ~link() {//--------------------------------------------銷燬連結串列 node<T>* p; p = head->getnext(); while (p != NULL) { delete head; head = p; p = p->getnext(); } }// }; class officer { friend ostream& operator<<(ostream& out, officer& obj); friend istream& operator>>(istream& in, officer& obj); friend ofstream& operator<<(ofstream& outfile, officer& obj);//--------輸出到檔案 friend ifstream& operator>>(ifstream& infile, officer& obj);//---------讀取檔案 private: string id_card; string name; string sex; int age; string post; int money; public://---------------------------------私有屬性管理方法 officer() { id_card = ""; name = ""; sex = ""; age = 0; post = ""; money = 0; } officer(officer& obj) { this->id_card = obj.getid(); this->name = obj.getname(); this->sex = obj.getsex(); this->age = obj.getage(); this->money = obj.getmoney(); this->post = obj.getpost(); } officer& operator=(officer& obj) { this->id_card = obj.getid(); this->name = obj.getname(); this->sex = obj.getsex(); this->age = obj.getage(); this->money = obj.getmoney(); this->post = obj.getpost(); return *this; } bool operator==(officer& obj) { if (this->getid() == obj.getid() && this->getname() == obj.getname() && this->getsex() == obj.getsex() && this->getage() == obj.getage() && this->getpost() == obj.getpost() && this->getmoney() == obj.getmoney()) { return true; } return false; } bool operator!=(officer& obj) { if (this->getid() == obj.getid()) { return false; } return true; } bool operator>(officer& obj) { if (this->getmoney() > obj.getmoney()) { return true; } return false; } bool operator<(officer& obj) { if (this->getmoney() < obj.getmoney()) { return true; } return false; } void setpost(string post) { this->post = post; } void setmoney(int money) { this->money = money; } void setid(string id) { id_card = id; } void setname(string name) { this->name = name; } void setsex(string sex) { this->sex = sex; } void setage(int age) { this->age = age; } string getid() { return id_card; } string getname() { return name; } string getsex() { return sex; } int getage() { return age; } string getpost() { return post; } int getmoney() { return money; } }; ostream& operator<<(ostream& out, officer& obj) { out << obj.getid() << "t"; out << obj.getname() << "t"; out << obj.getsex() << "t"; out << obj.getage() << "t"; out << obj.getpost() << "t"; out << obj.getmoney() << "t"; // cout << endl; return out; } istream& operator>>(istream& in, officer& obj) { cout << "身份證(18位元):"; id_here: in >> obj.id_card; if (obj.getid() == "00") { return in; } else if (obj.getid().length() != 18) { cout << "輸入格式不規範請重新輸入:"; goto id_here; } //if (judgecin == 1) { // return in; //} cout << "姓名:"; in >> obj.name; cout << "性別:"; sex_here: in >> obj.sex; if (obj.getid() == "00") { return in; } else if (obj.getsex() != "男" && obj.getsex() != "女") { cout << "請輸入準確的性別:"; goto sex_here; } cout << "年齡:"; string age; age_here: in >> age; if (obj.getid() == "00") { return in; } else if (mynum(age) || age.length() > 3) { cout << "輸入不規範請重新輸入:"; goto age_here; } obj.age = atoi(age.c_str()); cout << "職位:"; post_here: in >> obj.post; if (obj.getid() == "00") { return in; } else if (obj.getpost() != "監獄長" && obj.getpost() != "探長" && obj.getpost() != "參謀長" && obj.getpost() != "大警司" && obj.getpost() != "小警司") { cout << "請輸入職位(監獄長,探長,參謀長,大警司,小警司):"; goto post_here; } if (obj.getpost() == "監獄長") { obj.money = 30000; } else if (obj.getpost() == "探長") { obj.money = 24000; } else if (obj.getpost() == "參謀長") { obj.money = 24500; } else if (obj.getpost() == "大警司") { obj.money = 20000; } else if (obj.getpost() == "小警司") { obj.money = 18000; } return in; } ofstream& operator<<(ofstream& outfile, officer& obj) { outfile << obj.getid() << " " << obj.getname() << " " << obj.getsex() << " " << obj.getage() << " " << obj.getpost() << " " << obj.getmoney();// << endl; return outfile; } ifstream& operator>>(ifstream& infile, officer& obj) { string post1; int money1; string id1; string name1; string sex1; int age1; infile >> id1 >> name1 >> sex1 >> age1 >> post1 >> money1; obj.setid(id1); obj.setname(name1); obj.setsex(sex1); obj.setage(age1); obj.setpost(post1); obj.setmoney(money1); return infile; } int main() { //link<officer> myarray; link<int> myarray; char menun; while (1) { menun = off_menu(); if (menun == '1') { system("cls"); int len; cout << "請輸入您要增加節點的個數:"; cin >> len; for (int i = 0; i < len; i++) { myarray.addnode(); system("cls"); } } else if (menun == '2') { myarray.delnode(); } else if (menun == '3') { myarray.altenode(); } else if (menun == '4') { myarray.selnode(); } else if (menun == '5') { cout << "身份證ttt姓名t性別t年齡t職位t工資" << endl; myarray.printlink(); } else if (menun == '6') { break; } system("cls"); } return 0; } char off_menu() { char n; n = '0'; system("cls"); cout << "nnn"; cout << "ttttt-------歡迎使用本資訊管理系統-------" << endl; cout << "ttttt*t ttt *" << endl; cout << "ttttt*t 1.錄入員工資訊t *" << endl; cout << "ttttt*t ttt *" << endl; cout << "ttttt*t 2.刪除員工資訊t *" << endl; cout << "ttttt*t ttt *" << endl; cout << "ttttt*t 3.修改員工資訊t *" << endl; cout << "ttttt*t ttt *" << endl; cout << "ttttt*t 4.查詢員工資訊t *" << endl; cout << "ttttt*t ttt *" << endl; cout << "ttttt*t 5.檢視員工資訊t *" << endl; cout << "ttttt*t ttt *" << endl; cout << "ttttt*t 6.退出該系統tt *" << endl; cout << "ttttt*t ttt *" << endl; cout << "ttttt------------------------------------" << endl; cout << "———————————————————————————————————————————————————————----------" << endl; cout << "———————————————————————————————————————————————————————----------" << endl; cout << "please your choose:"; while (1) { n = _getch(); if (n >= '1' && n <= '6') { break; } } cout << endl; return n; }
總結:
理解了泛型會對python等解釋性語言有更好的理解。希望大家能夠好好理解這個專案,在博主的基礎之上更上一層樓
到此這篇關於基於C++泛型程式設計職工管理系統的文章就介紹到這了,更多相關C++泛型程式設計職工管理系統內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45