昨晚,正在准备考研的小C叫我帮他调试一下他的代码,看了他发的CPP,居然只有一个main函数,一大堆a1,b1,c1等变量,确实改得蛋疼,不如自己重写一个....

 

类说明:

1、Person

     抽象的类,可用该类派生出:学生、老师、清洁工等

 

2、Student

     学生类(派生自Person)

 

3、Node

     单链表的节点类

     包含:1、一个指向下一节点的指针

              2、一个指向学习类对象的指针

 

4、ListMgr

     链表管理器类的声明,包括链表排序、遍历、交换、添加、删除等方法

 

5、ListItr

     链表的迭代类声明(可省略)

 

6、AppClass

     应用程序实例类 —— 用来与用户进行交互操作

 

具体代码如下:

 

Person.h

// // Person 抽象的类 // 可用该类派生出:学生、老师、清洁工等 #ifndef PERSON #define PERSON 1 class Person { public: Person(); virtual int GetKey() = 0; }; #endif // end of file Person.h //

 

Person.cpp

// // Person抽象父类的具体实现 #include "Person.h" Person::Person() { } // end of file Person.h //

 

Student.h

// // Student.h 学生类 #ifndef STUDENT #define STUDENT #include "Person.h" class Student : public Person { public: Student(); Student(char [],int,int,int); char* GetName(); int GetMath(); int GetEnglish(); int GetTotal(); int GetKey(); private: char m_szName[20]; // 学生姓名 int m_nMath; // 数学成绩 int m_nEnglish; // 英语成绩 int m_nTotal; // 总分 int m_nKey; // 学生编号 (唯一编号,类似数据库的主键) }; #endif // end of file Student.h //

 

Student.cpp

// // Student 学生类的具体实现 #include "Student.h" #include <string.h> /************************************************************************/ /* 函数说明:默认构造函数 /* 函数参数:无 /* 返 回 值:无 /* 备注信息:无 /************************************************************************/ Student::Student() { } /************************************************************************/ /* 函数说明:默认构造函数 /* 函数参数:szName 学生姓名 /* nMath 数学成绩 /* nEnglish 英语成绩 /* nKey 学生编号 /* 返 回 值:无 /* 备注信息:无 /************************************************************************/ Student::Student(char szName[],int nMath,int nEnglish,int nKey) { strncpy(m_szName,szName,strlen(m_szName)); m_nKey = nKey; m_nMath = nMath; m_nEnglish = nEnglish; m_nTotal = nEnglish + nMath; } /************************************************************************/ /* 函数说明:获取学生姓名 /* 函数参数:无 /* 返 回 值:char* /* 备注信息:无 /************************************************************************/ char* Student::GetName() { return m_szName; } /************************************************************************/ /* 函数说明:获取学生数学成绩 /* 函数参数:无 /* 返 回 值:int /* 备注信息:无 /************************************************************************/ int Student::GetMath() { return m_nMath; } /************************************************************************/ /* 函数说明:获取学生英语成绩 /* 函数参数:无 /* 返 回 值:int /* 备注信息:无 /************************************************************************/ int Student::GetEnglish() { return m_nEnglish; } /************************************************************************/ /* 函数说明:获取学生总成绩 /* 函数参数:无 /* 返 回 值:int /* 备注信息:无 /************************************************************************/ int Student::GetTotal() { return m_nTotal; } /************************************************************************/ /* 函数说明:获取学生编号 /* 函数参数:无 /* 返 回 值:int /* 备注信息:无 /************************************************************************/ int Student::GetKey() { return m_nKey; } // end of file Student.cpp //

 

Node.h

// // Node 单链表的节点类 // 包含:1、一个指向下一节点的指针 // 2、一个指向学习类对象的指针 // #ifndef NODE #define NODE #include "Student.h" class Node { public: Node(Student *); Node* GetNext(); Student* GetStudent(); void SetStudent(Student* ps); void SetNext(Node *); private: Student* m_pStudent; // 该节点对应学生对象的指针 Node* m_pNext; // 指向下一个节点 }; #endif // end of file Node.h //

 

Node.cpp

// // Node 单链表的节点类 —— 具体实现方法 // #include "Node.h" /************************************************************************/ /* 函数说明:构造函数,以便初始化成员变量 /* 函数参数:theObj 学习类对象的指针 /* 返 回 值:无 /* 备注信息:无 /************************************************************************/ Node::Node(Student *theObj) { m_pStudent = theObj; m_pNext = 0; } /************************************************************************/ /* 函数说明:获取下一个节点的指针 /* 函数参数:无 /* 返 回 值:Node* 下一节点的指针 /* 备注信息:无 /************************************************************************/ Node* Node::GetNext() { return m_pNext; } /************************************************************************/ /* 函数说明:获取该学生对象的指针 /* 函数参数:无 /* 返 回 值:Student* 学生对象的指针 /* 备注信息:无 /************************************************************************/ Student* Node::GetStudent() { return m_pStudent; } /************************************************************************/ /* 函数说明:获取该学生对象的指针 /* 函数参数:无 /* 返 回 值:Student* 学生对象的指针 /* 备注信息:无 /************************************************************************/ void Node::SetStudent(Student* ps) { m_pStudent = ps; } /************************************************************************/ /* 函数说明:设置下一个节点的指针 /* 函数参数:nextNode 下一节点的指针 /* 返 回 值:无 /* 备注信息:无 /************************************************************************/ void Node::SetNext(Node *nextNode) { m_pNext = nextNode; } // end of file Node.cpp //

 

ListMgr.h

// // ListMgr 链表管理器类的声明 // #ifndef LISTMGR #define LISTMGR #include "Node.h" #include "Student.h" class ListMgr { public: ListMgr(); void Insert(Student *); Student* Find(int); int Remove(int); Node* GetFirst(); void Order(bool asc = true); void SwapNode(Node*,Node*); bool Compare(int Left, int Right, bool big=true); private: Node* first; // 头节点 }; #endif // end of file ListMgr.h //

 

ListMgr.cpp

// // ListMgr 链表管理器类的具体实现 // #include "ListMgr.h" #include <iostream> #include <assert.h> using namespace std; /************************************************************************/ /* 函数说明:构造函数 /* 函数参数:无 /* 返 回 值:无 /* 备注信息:初始化头结点 /************************************************************************/ ListMgr::ListMgr() { first = 0; } /************************************************************************/ /* 函数说明:在单链表中插入一个元素 /* 函数参数:theStudent 元素指针 /* 返 回 值:无 /* 备注信息:无 /************************************************************************/ void ListMgr::Insert(Student *theStudent) { Node *newNode,*current,*previous; Student *currentStudent; newNode = new Node(theStudent); int newKey = theStudent->GetKey(); if( !newNode ) { cout<<"/n无法创建一个结点./n"<<endl; return; } if (first == 0) { first = newNode; } else { int firstNode = true; current = first; while(current != 0) { currentStudent = current->GetStudent(); if(newKey < currentStudent->GetKey()) break; previous = current; current = current->GetNext(); firstNode = false; } // 如果是第一次插入,则将前一个节点指向这个新的节点 if(!firstNode) previous->SetNext(newNode); else first = newNode; // 将新的节点存放在当前链表中 newNode->SetNext(current); } } /************************************************************************/ /* 函数说明:在单链表中查找一个元素 /* 函数参数:searchNum 节点的关键字,即学生编号 /* 返 回 值:成功返回该节点的指针,否则返回0 /* 备注信息:无 /************************************************************************/ Student* ListMgr::Find(int searchNum) { Student *currentStudent; Node *current; current = first; while(current != 0) { currentStudent = current->GetStudent(); if(searchNum == currentStudent->GetKey()) return currentStudent; current = current->GetNext(); } return 0; } /************************************************************************/ /* 函数说明:在单链表中删除一个元素 /* 函数参数:searchNum 节点的关键字 /* 返 回 值:成功返回true,否则返回false /* 备注信息:无 /************************************************************************/ int ListMgr::Remove(int searchNum) { Student *currentStudent; Node *current,*previous,*next; if(first == 0) // 如果当前链表为空则直接返回 return false; int firstNode = true; current = first; while(current != 0) { currentStudent = current->GetStudent(); if(searchNum == currentStudent->GetKey()) break; previous = current; current = current->GetNext(); firstNode = false; // 不是头节点 } if(current == 0) // 没有找到该节点则返回 return false; if(!firstNode) { next = current->GetNext(); // 先获取该节点的后一个节点 previous->SetNext(next); } else first = current->GetNext(); // 将后一个节点设置为当前节点 // 这里内存释放有点问题,未调试完毕 // delete current->GetStudent(); // 删除学生对象的内存空间 // delete current; // 删除节点对象的内存空间 return true; // 成功删除某节点 } /************************************************************************/ /* 函数说明:在单链表中获取头节点元素 /* 函数参数:无 /* 返 回 值:Node* 头节点元素 /* 备注信息:无 /************************************************************************/ Node* ListMgr::GetFirst() { return first; } /************************************************************************/ /* 函数说明:比较大小函数 /* 函数参数:big==true 升序 ==false 降序可用来控制排序升序降序 /* 返 回 值:bool值 是否大于或小于 /* 备注信息:无 /************************************************************************/ bool ListMgr::Compare(int Left, int Right, bool big) { return big ? Left>Right : Left<Right; } /************************************************************************/ /* 函数说明:根据学生总分进行排序 /* 函数参数:asc true升序// false降序 /* 返 回 值:无 /* 备注信息:找最值然后与前面的交换 重复这样的过程 完成排序 /************************************************************************/ void ListMgr::Order(bool asc /*= true*/) { for (Node *pNodei=first; pNodei!=NULL; pNodei=pNodei->GetNext()) { Node* pNoteM = pNodei; Node *pNodej = pNodei->GetNext(); for (; pNodej!=NULL; pNodej=pNodej->GetNext()) { if(Compare(pNoteM->GetStudent()->GetTotal(), pNodej->GetStudent()->GetTotal(), asc)) { pNoteM = pNodej;//记录最值 } } SwapNode(pNodei, pNoteM);//交换本节点和最值 } } /************************************************************************/ /* 函数说明:交换两个结点的位置 /* 函数参数:无 /* 返 回 值:无 /* 备注信息:无 /************************************************************************/ void ListMgr::SwapNode(Node *pLeft,Node *pRight) { assert(pLeft!=NULL && pRight!=NULL); Student* temp = pLeft->GetStudent(); pLeft->SetStudent(pRight->GetStudent()); pRight->SetStudent(temp); } // end of file ListMgr.cpp //

 

ListItr.h

// // ListItr 链表的迭代类声明 // #ifndef LISTITR #define LISTITR #include "Node.h" #include "ListMgr.h" class ListItr { public: ListItr(ListMgr *); Student* GetNext(); private: Node* m_pCurNode; // 当前的节点 ListMgr* m_pList; // 当前链表管理器的指针 }; #endif // end of file ListItr.h //

 

ListItr.cpp

// // ListMgr 链表的迭代类 —— 具体实现方法 // #include "ListItr.h" /************************************************************************/ /* 函数说明:构造函数 /* 函数参数:whichList 链表管理器的指针 /* 返 回 值:无 /* 备注信息:用来初始化链表管理器对象的指针 /************************************************************************/ ListItr::ListItr(ListMgr *whichList) { m_pCurNode = 0; m_pList = whichList; } /************************************************************************/ /* 函数说明:在链表管理器实例中获取下一个节点的学生数据 /* 函数参数:无 /* 返 回 值:成功返回该数据,否则返回0 /* 备注信息:无 /************************************************************************/ Student* ListItr::GetNext() { if(m_pCurNode == 0) m_pCurNode = m_pList->GetFirst(); else m_pCurNode = m_pCurNode->GetNext(); if(m_pCurNode != 0) return m_pCurNode->GetStudent(); else return 0; } // end of file ListItr.cpp //

 

AppClass.h

// // AppClass.h 应用程序实例类 —— 用来与用户进行交互操作 #ifndef APPCLASS #define APPCLASS #include "ListMgr.h" // // 主界面程序交互 —— 当前操作类型 #define INSERT 1 // 添加学生 #define REMOVE 2 // 删除学生 #define VIEW 3 // 查看全部 #define ORDER 4 // 升序 #define ORDER_BY_DESC 5 // 降序 #define QUIT 6 // 退出程序 class AppClass { private: ListMgr *m_pListMgr; // 链表管理器指针 int ShowMenu(); // 显示菜单 void AddStudent(); // 添加学生 void RemoveStudent(); // 删除学生 void ViewAll(); // 默认 void Order(); // 升序 void OrderByDesc(); // 降序 public: AppClass(); void Run(); }; #endif // end of file AppClass.h //

 

AppClass.cpp

// // AppClass 应用程序实例类 —— 具体实现方法 // #include "AppClass.h" #include "ListMgr.h" #include "ListItr.h" #include "Student.h" #include <iostream> using namespace std; /************************************************************************/ /* 函数说明:构造函数 /* 函数参数:无 /* 返 回 值:无 /* 备注信息:无 /************************************************************************/ AppClass::AppClass() { m_pListMgr = new ListMgr(); // 第三处内存泄露 } /************************************************************************/ /* 函数说明:启动应用程序实例 /* 函数参数:无 /* 返 回 值:无 /* 备注信息:无 /************************************************************************/ void AppClass::Run() { int nChoice = ShowMenu(); while(nChoice != QUIT) { switch (nChoice) { case INSERT: AddStudent(); break; case REMOVE: RemoveStudent(); break; case VIEW: ViewAll(); break; case ORDER: Order(); ViewAll(); break; case ORDER_BY_DESC: OrderByDesc(); ViewAll(); break; case QUIT: break; default: cout<<"你的选择有误,请重试!"<<endl; } nChoice = ShowMenu(); } } /************************************************************************/ /* 函数说明:显示菜单项 /* 函数参数:无 /* 返 回 值:操作类型 /* 备注信息:无 /************************************************************************/ int AppClass::ShowMenu() { cout<<"/n1、添加一个学生"; cout<<"/n2、删除一个学生"; cout<<"/n3、默认方式/t(按添加的先后顺序进行排列)"; cout<<"/n4、按升序查看"; cout<<"/n5、按降序查看"; cout<<"/n6、退出程序/n"; cout<<"/n请选择一项: "; int nChoice = 0; cin>>nChoice; return nChoice; } /************************************************************************/ /* 函数说明:新增一个学生 /* 函数参数:无 /* 返 回 值:无 /* 备注信息:无 /************************************************************************/ void AppClass::AddStudent() { Student *newStudent,*prevStudent; int nID; char szName[20] = ""; int nMath = 0; int nEnglish = 0; cout<<"/n请依次输入:/n编号/t姓名/t数学/t英语"<<endl; cout<<"(提示:以空格分割或TAB键即可.)/n"; cin>>nID>>szName>>nMath>>nEnglish; prevStudent = m_pListMgr->Find(nID); // 先判断编号是否存在 if(prevStudent != 0) { cout<<"/n添加失败! (错误原因:当前学生编号已经存在.)/n"; return; } newStudent = new Student(szName,nMath,nEnglish,nID); // 第二处内存泄露 m_pListMgr->Insert(newStudent); } /************************************************************************/ /* 函数说明:删除一个学生 /* 函数参数:无 /* 返 回 值:无 /* 备注信息:无 /************************************************************************/ void AppClass::RemoveStudent() { int nID = 0; int nResult = 0; cout<<"请输入学生编号:"; cin>>nID; nResult = m_pListMgr->Remove(nID); if(nResult) cout<<"删除成功!"<<endl; else cout<<"删除失败!(请先检查该编号是否存在.)"<<endl; } /************************************************************************/ /* 函数说明:查看全部 /* 函数参数:无 /* 返 回 值:无 /* 备注信息:按默认添加的顺序进行排列 /************************************************************************/ void AppClass::ViewAll() { Student *current; ListItr *theIterator; theIterator = new ListItr(m_pListMgr); // 第一处内存泄漏 current = theIterator->GetNext(); bool bEmpty = false; // 检查是当前链表是否为空 if(current == 0) bEmpty = true; cout<<"/n编号/t姓名/t数学/t英语/t总分"<<endl; while(current != 0) { cout<<current->GetKey()<<"/t"; cout<<current->GetName()<<"/t"; cout<<current->GetMath()<<"/t"; cout<<current->GetEnglish()<<"/t"; cout<<current->GetTotal()<<endl; current = theIterator->GetNext(); } if(bEmpty) cout<<"当前记录为空!/n"; } /************************************************************************/ /* 函数说明:排序并查看(升序) /* 函数参数:无 /* 返 回 值:无 /* 备注信息:无 /************************************************************************/ void AppClass::Order() { m_pListMgr->Order(); } /************************************************************************/ /* 函数说明:排序并查看(降序) /* 函数参数:无 /* 返 回 值:无 /* 备注信息:无 /************************************************************************/ void AppClass::OrderByDesc() { m_pListMgr->Order(false); } // end of file AppClass.cpp //