Ex8_5_1.cpp
上传用户:wuzhousb
上传日期:2022-07-12
资源大小:380k
文件大小:5k
源码类别:

书籍源码

开发平台:

Visual C++

  1. //【例8.5_1】根据赋值兼容规则可以用基类的指针指向派生类对象,如果由该指针撤销
  2. //派生类对象,则必须将析构函数说明为虚函数,实现多态性,自动调用派生类析构函数。
  3. #include<iostream>
  4. #include<string>
  5. using namespace std;
  6. enum Tsex{mid,man,woman};
  7. struct course{
  8. string coursename;
  9. int grade;
  10. };
  11. class Person{
  12. string IdPerson; //身份证号
  13. string Name; //姓名
  14. Tsex Sex; //性别
  15. int Birthday; //生日,格式1986年8月18日写作19860818
  16. string HomeAddress; //家庭地址
  17. public:
  18. Person(string,string,Tsex,int,string);
  19. Person();
  20. Person(Person &ps);
  21. virtual ~Person();
  22. Person & operator=(Person &);
  23. void PrintPersonInfo();
  24. };
  25. Person::Person(string id,string name,Tsex sex,int birthday,string homeadd){
  26. IdPerson=id;
  27. Name=name;
  28. Sex=sex;
  29. Birthday=birthday;
  30. HomeAddress=homeadd;
  31. }
  32. Person::Person(){
  33. IdPerson="#";Name="#";Sex=mid;
  34. Birthday=0;HomeAddress="#";
  35. }
  36. Person::Person(Person &ps){
  37. IdPerson=ps.IdPerson;
  38. Name=ps.Name;
  39. Sex=ps.Sex;
  40. Birthday=ps.Birthday;
  41. HomeAddress=ps.HomeAddress;
  42. }
  43. Person::~Person(){cout<<"Person析构函数"<<endl;}
  44. Person & Person::operator=(Person &ps){
  45. IdPerson=ps.IdPerson;
  46. Name=ps.Name;
  47. Sex=ps.Sex;
  48. Birthday=ps.Birthday;
  49. HomeAddress=ps.HomeAddress;
  50. return *this;
  51. }
  52. void Person::PrintPersonInfo(){
  53. int i;
  54. cout<<"身份证号:"<<IdPerson<<'n'<<"姓名:"<<Name<<'n'<<"性别:";
  55. if(Sex==man)cout<<"男"<<'n';
  56. else if(Sex==woman)cout<<"女"<<'n';
  57.      else cout<<" "<<'n';
  58. cout<<"出生年月日:";
  59. i=Birthday;
  60. cout<<i/10000<<"年";
  61. i=i%10000;
  62. cout<<i/100<<"月"<<i%100<<"日"<<'n'<<"家庭住址:"<<HomeAddress<<'n';
  63. }
  64. class Student:public Person{//定义派生的学生类
  65. string NoStudent;//学号
  66. course cs[30];//30门课程与成绩
  67. public:
  68. Student(string id,string name,Tsex sex,int birthday,string homeadd,string nostud);
  69. //注意派生类构造函数声明方式
  70. Student();
  71. Student(Student &Std);
  72. ~Student();
  73. Student & operator=(Student &Std);
  74. int SetCourse(string,int);
  75. int GetCourse(string);
  76. void PrintStudentInfo();
  77. }; //这里省略了一些成员函数,如赋学号、取学号等
  78. Student::Student(string id,string name,Tsex sex,int birthday,string homeadd,string nostud)
  79.              :Person(id,name,sex,birthday,homeadd){//注意Person参数表不用类型
  80. int i;
  81. NoStudent=nostud;
  82. for(i=0;i<30;i++){//课程与成绩清空,将来由键盘输入 
  83. cs[i].coursename="#";
  84. cs[i].grade=0;
  85. }
  86. }
  87. Student::Student(){//基类缺省的无参数构造函数不必显式给出
  88. int i;
  89. NoStudent="#";
  90. for(i=0;i<30;i++){//课程与成绩清空,将来由键盘输入 
  91. cs[i].coursename="#";
  92. cs[i].grade=0;
  93. }
  94. }
  95. Student::Student(Student &Std):Person(Std){//按赋值兼容规则Std可为Person实参
  96. int i;
  97. NoStudent=Std.NoStudent;
  98. for(i=0;i<30;i++){
  99. cs[i].coursename=Std.cs[i].coursename;
  100. cs[i].grade=Std.cs[i].grade;
  101. }
  102. }
  103. Student::~Student(){cout<<"Student析构函数"<<endl;}//基类析构函数不必显式给出
  104. Student & Student::operator=(Student &Std){
  105. int i;
  106. this->Person::operator=(Std);
  107. NoStudent=Std.NoStudent;
  108. for(i=0;i<30;i++){
  109. cs[i].coursename=Std.cs[i].coursename;
  110. cs[i].grade=Std.cs[i].grade;
  111. }
  112. return *this;
  113. }
  114. int Student::SetCourse(string coursename,int grade){
  115. int i;
  116. bool b=false;//标识新输入的课程,还是更新成绩
  117. for(i=0;i<30;i++){
  118. if(cs[i].coursename=="#"){
  119. //判表是否进入未使用部分(如有对应删除应按顺序表方式)
  120. cs[i].coursename=coursename;
  121. cs[i].grade=grade;
  122. b=false;
  123. break;
  124. }
  125. else if(cs[i].coursename==coursename){
  126. cs[i].grade=grade;
  127. b=true;
  128. break;
  129. }
  130. }
  131. if(i==30) return 0;//成绩表满返回0
  132. if(b) return 1;//修改成绩返回1
  133. else return 2;//登记成绩返回2
  134. }
  135. int Student::GetCourse(string coursename){
  136. int i;
  137. for(i=0;i<30;i++)
  138. if(cs[i].coursename=="#") break;//无此句,stcpy()会出错
  139. else if(cs[i].coursename==coursename) return cs[i].grade;
  140. return -1;
  141. }//找到返回成绩,未找到返回-1
  142. void Student::PrintStudentInfo(){
  143. int i;
  144. cout<<"学号:"<<NoStudent<<'n';
  145. PrintPersonInfo();
  146. for(i=0;i<30;i++)//打印各科成绩
  147. if(cs[i].coursename!="#")cout<<cs[i].coursename<<'t'<<cs[i].grade<<'n';
  148. else break;
  149. cout<<"--------完-------- "<<endl;
  150. }
  151. int main(void){
  152. string temp;
  153. int i,k;
  154. Student stu1("320102811226161","朱海鹏",man,19811226,"南京市黄浦路1号","06000123");
  155. cout<<"请输入各科成绩:"<<'n';//为简单仅以一个学生为例。完整应输入学号,查找,再操作
  156. while(1){//输入各科成绩,输入"end"停止
  157. cin>>temp;//输入格式:物理  80
  158. if(temp=="end") break;
  159. cin>>k;
  160. i=stu1.SetCourse(temp,k);
  161. if(i==0)cout<<"成绩列表已满!"<<'n';
  162. else if(i==1)cout<<"修改成绩"<<'n';
  163.      else cout<<"登记成绩"<<'n';
  164.     }
  165. stu1.PrintStudentInfo();
  166. Person *pper4;
  167. Student *pstu4=new Student;       //动态建立对象*stu4
  168. *pstu4=stu1;        //把stu1的数据拷入*stu4
  169. pstu4->PrintStudentInfo();
  170. pper4=pstu4;
  171. delete pper4; //用基类指针撤销派生类,动态生成的对象必须显式撤销
  172. return 0;
  173. }