作业5-继承和派生

这一生的挚爱 提交于 2020-03-22 16:53:51

1.全面的MyString

输出:

1. abcd-efgh-abcd-
2. abcd-
3.
4. abcd-efgh-
5. efgh-
6. c
7. abcd-
8. ijAl-
9. ijAl-mnop
10. qrst-abcd-
11. abcd-qrst-abcd- uvw xyz
about
big
me
take
abcd
qrst-abcd-

  1 /*使程序输出指定结果*/ 
  2 #include <cstdlib>
  3 #include <iostream>
  4 using namespace std;
  5 int strlen(const char * s) 
  6 {    int i = 0;
  7     for(; s[i]; ++i);
  8     return i;
  9 }
 10 
 11 void strcpy(char * d,const char * s)
 12 {
 13     int i = 0;
 14     for( i = 0; s[i]; ++i)
 15         d[i] = s[i];
 16     d[i] = 0;
 17         
 18 }
 19 
 20 int strcmp(const char * s1,const char * s2)
 21 {
 22     for(int i = 0; s1[i] && s2[i] ; ++i) {
 23         if( s1[i] < s2[i] )
 24             return -1;
 25         else if( s1[i] > s2[i])
 26             return 1;
 27     }
 28     return 0;
 29 }
 30 
 31 void strcat(char * d,const char * s)
 32 {
 33     int len = strlen(d);
 34     strcpy(d+len,s);
 35 }
 36 
 37 class MyString
 38 {
 39 // 在此处补充你的代码
 40     char *p;
 41 public:
 42     MyString(const char * s = NULL) { //擅于利用缺省的参数,不要再写一个 
 43         if(s) {
 44             p = new char[strlen(s) + 1];
 45             strcpy(p,s);
 46         }
 47         else
 48             p = NULL;
 49 
 50     }
 51     ~MyString() { if(p) delete [] p; } 
 52     MyString(const MyString & s){
 53         if(s.p==NULL) p = NULL;
 54         else{
 55             p = new char[strlen(s.p) + 1];
 56             strcpy(p,s.p);
 57         }
 58     }
 59     MyString & operator=(const MyString & s) {
 60         if(p) delete [] p;
 61         if(s.p==NULL){
 62             p = NULL; return * this;
 63         }
 64         p = new char[strlen(s.p)+1]; 
 65         strcpy(p, s.p);
 66         return * this; 
 67     }
 68     MyString & operator=(const char * s) {
 69         if(p) delete [] p;
 70         if(s==NULL){
 71             p = NULL; return * this;
 72         }
 73         p = new char[strlen(s)+1]; 
 74         strcpy(p, s);
 75         return * this; 
 76     }
 77     char & operator[](const int i){
 78         return p[i];
 79     }
 80     friend MyString operator+(const MyString & a, const MyString & b){
 81         MyString ans;
 82         ans.p = new char[strlen(a.p)+strlen(b.p)+1];
 83         strcpy(ans.p, a.p);
 84         strcat(ans.p, b.p); //不能改变原来的a 
 85         return ans;
 86     }
 87     MyString & operator+=(const char * s) {
 88         MyString temp(s);
 89         *this = *this+temp;
 90         return * this; 
 91     }
 92     bool operator<(const MyString s){
 93         return (strcmp(p, s.p)==-1);
 94     }
 95     bool operator>(const MyString s){
 96         return (strcmp(p, s.p)==1);
 97     }
 98     bool operator==(const MyString s){
 99         return (strcmp(p, s.p)==0);
100     }
101     char * operator()(int start, int len){
102         char *temp = new char[len+1];
103         for (int i = start; i < start+len; i++){
104             temp[i-start] = p[i];
105         }
106         temp[len] = '\0';
107         return temp;
108     } 
109     friend ostream & operator<<(ostream & o, const MyString & s){
110         if(s.p==NULL )return o; // 空指针就不输出了 
111         o<<s.p;
112         return o;
113     } 
114     
115 };
116 
117 
118 int CompareString( const void * e1, const void * e2)
119 {
120     MyString * s1 = (MyString * ) e1;
121     MyString * s2 = (MyString * ) e2;
122     if( * s1 < *s2 ) //重载小于号 
123     return -1;
124     else if( *s1 == *s2)
125     return 0;
126     else if( *s1 > *s2 ) //重载大于号 
127     return 1;
128 }
129 
130 int main()
131 {
132     MyString s1("abcd-"),s2,s3("efgh-"),s4(s1); //构造函数、复制构造函数 
133     MyString SArray[4] = {"big","me","about","take"};
134     cout << "1. " <<s1<<s2<<s3<< s4<< endl; //重载流插入  不能读 空指针 
135     s4 = s3; //重载等于号 
136     s3 = s1 + s3; // 重载+号 
137     cout << "2. " << s1 << endl;
138     cout << "3. " << s2 << endl;
139     cout << "4. " << s3 << endl;
140     cout << "5. " << s4 << endl;
141     cout << "6. " << s1[2] << endl;
142     s2 = s1;
143     s1 = "ijkl-"; //重载等于号 
144     s1[2] = 'A' ; // 重载中括号 
145     cout << "7. " << s2 << endl;
146     cout << "8. " << s1 << endl;
147     s1 += "mnop"; //重载+= 
148     cout << "9. " << s1 << endl;
149     s4 = "qrst-" + s2;
150     cout << "10. " << s4 << endl;
151     s1 = s2 + s4 + " uvw " + "xyz";
152     cout << "11. " << s1 << endl;
153     qsort(SArray,4,sizeof(MyString),CompareString);
154     for( int i = 0;i < 4;i ++ )
155     cout << SArray[i] << endl;
156     //s1的从下标0开始长度为4的子串
157     cout << s1(0,4) << endl; //重载小括号 
158     //s1的从下标5开始长度为10的子串
159     cout << s1(5,10) << endl;  
160     return 0;
161 }

备注:这道题应该就是为了第二道题做铺垫,让我们感受一下继承的便捷。这道题的启发在于cout不能输出空指针!!!如果输出空指针,之后的输出就都输出不了了。

2.继承自string的MyString

 1 #include <cstdlib>
 2 #include <iostream>
 3 #include <string>
 4 #include <algorithm>
 5 using namespace std;
 6 class MyString:public string
 7 {
 8 // 在此处补充你的代码
 9 public:
10     MyString(): string() {}  
11     MyString(const string s): string(s){}
12     MyString(const char * s): string(s){}//为什么要写这一行 
13     string operator()(int start, int len){
14         return substr(start, len);
15     } 
16 };
17 
18 
19 int main()
20 {
21     MyString s1("abcd-"),s2,s3("efgh-"),s4(s1);
22     MyString s5 = "abds";
23     //MyString SArray[4] = {"big","me","about","take"};
24     cout << "1. " << s1 << s2 << s3<< s4<< endl;
25     s4 = s3;
26     s3 = s1 + s3;
27     cout << "2. " << s1 << endl;
28     cout << "3. " << s2 << endl;
29     cout << "4. " << s3 << endl;
30     cout << "5. " << s4 << endl;
31     cout << "6. " << s1[2] << endl;
32     s2 = s1;
33 //    s1 = "ijkl-";
34     s1[2] = 'A' ;
35     cout << "7. " << s2 << endl;
36     cout << "8. " << s1 << endl;
37     s1 += "mnop";
38     cout << "9. " << s1 << endl;
39     s4 = "qrst-" + s2;
40     cout << "10. " << s4 << endl;
41     s1 = s2 + s4 + " uvw " + "xyz";
42     cout << "11. " << s1 << endl;
43         sort(SArray,SArray+4);
44     for( int i = 0;i < 4;i ++ )
45     cout << SArray[i] << endl;
46     //s1的从下标0开始长度为4的子串
47     cout << s1(0,4) << endl;
48     //s1的从下标5开始长度为10的子串
49     cout << s1(5,10) << endl;
50     return 0;
51 }

备注:注意标黄的一行,如果少了会编译报错。问了助教学长,答复是,做MyString a="xxx"的时候,实际上先把"xxx"变成了string,然后再变成MyString,需要两步隐式的类型转换,而这个是不支持的。

3.魔兽世界2

  1 #include <iostream>
  2 #include <string>
  3 #include<cstdio> 
  4 #include<cstring>
  5 using namespace std;
  6 //武士一共有 dragon 、ninja、iceman、lion、wolf 五种。每种武士都有编号、生命值、攻击力这三种属性
  7 //红方司令部按照iceman、lion、wolf、ninja、dragon的顺序循环制造武士。 
  8 //蓝方司令部按照lion、dragon、ninja、iceman、wolf的顺序循环制造武士。
  9 //编程规范:变量名中间字母大写,类名、函数名首字母大写
 10 //莫名其妙的问题看看循环的下标是不是写错了! 
 11 class Command; //复合关系 
 12 
 13 class Soldier{ //武士 
 14     private:
 15         Command *com; //属于哪个司令部 
 16         int kind; //是哪种武士 
 17         int id; //编号 
 18     public:
 19         Soldier(Command*p, int kindd, int idd);
 20         void Print(int time);
 21         static int life[5]; //生命值
 22         static string weapon[3]; //新加武器 
 23         static string name[5];  //dragon 、ninja、iceman、lion、wolf  
 24 }; 
 25 
 26 class Command{ //司令部 
 27     private:
 28         Soldier *mySoldier[1000]; //都有哪些士兵
 29         int HP; //总血量
 30         int color; //蓝方为1, 红方为0
 31         int sNum[5]; //存放每种士兵的数量 
 32         int curID; //当前制造到了第curID个士兵 
 33         int curkind; //当前制造的种类(用在该颜色的order里是第几个表示,即相对编号) 
 34         bool flag; //用来记录生命值用完了没有 
 35     public:
 36         static int order[2][5]; //制造顺序 
 37         void Init(int col, int life);
 38         bool Creat(int time); 
 39         ~Command();
 40     friend class Soldier; //友元关系不可继承
 41     friend class Dragon; 
 42     friend class Lion; 
 43 }; 
 44 
 45 class Dragon: public Soldier{
 46     string weap; //获得编号为n%3; 
 47     double morale;    //降生后其司令部剩余生命元的数量除以造dragon所需的生命元数量 
 48 public:
 49     Dragon(Command*p, int kindd, int idd):Soldier(p, kindd, idd),weap(weapon[idd%3]),morale(double(p->HP)/life[0]){}
 50     void Printinfo(){
 51         printf("It has a %s,and it's morale is %.2lf\n",weap.c_str(),morale);
 52     }
 53 }; 
 54 
 55 class Ninja: public Soldier{
 56     string weap1, weap2; //获得编号为 n%3 和 (n+1)%3的武器
 57 public:
 58     Ninja(Command*p, int kindd, int idd):Soldier(p, kindd, idd),weap1(weapon[idd%3]), weap2(weapon[(idd+1)%3]){}
 59     void Printinfo(){
 60         printf("It has a %s and a %s\n",weap1.c_str(), weap2.c_str());
 61     }
 62 }; 
 63 
 64 class Iceman: public Soldier{
 65     string weap;//获得编号为 n%3 的武器
 66 public:
 67     Iceman(Command*p, int kindd, int idd):Soldier(p, kindd, idd),weap(weapon[idd%3]){}
 68     void Printinfo(){
 69         printf("It has a %s\n",weap.c_str());
 70     }
 71 }; 
 72 
 73 class Lion: public Soldier{
 74     int loyalty; //它降生后其司令部剩余生命元的数目
 75 public:
 76     Lion(Command*p, int kindd, int idd):Soldier(p, kindd, idd),loyalty(p->HP){}
 77     void Printinfo(){
 78         printf("It's loyalty is %d\n", loyalty);
 79     }
 80 }; 
 81 
 82 class Wolf: public Soldier{
 83     
 84 }; 
 85 
 86 string Soldier::name[5]={"dragon","ninja","iceman","lion","wolf"};
 87 int Soldier::life[5];
 88 string Soldier::weapon[3] = {"sword", "bomb", "arrow"};
 89 int Command::order[2][5]={{2,3,4,1,0},{3,0,1,2,4}}; 
 90 
 91 Soldier::Soldier(Command *p, int kindd, int idd){
 92     com = p;
 93     kind = kindd;
 94     id = idd;
 95 }
 96 
 97 void Soldier::Print(int time){
 98     char color[6];
 99     if(com->color==1) strcpy(color, "blue"); //char字符串可以直接用=初始化,但不能这么赋值 
100     else strcpy(color, "red");
101     printf("%03d %s %s %d born with strength %d,%d %s in %s headquarter\n",
102         time, color, name[kind].c_str(), id, life[kind], com->sNum[kind],name[kind].c_str(),color); 
103 }
104 
105 void Command::Init(int col, int life){ //初始化 
106     color = col;
107     HP = life;
108     flag = false;
109     curID = 1;
110     curkind = 0;
111     memset(sNum, 0, sizeof(sNum)); 
112 }
113 
114 //string Soldier::name[5]={"dragon","ninja","iceman","lion","wolf"};
115 bool Command::Creat(int time){
116     if(flag) return false; //已经不能再造了 
117     int i, kind;
118     int orikind = curkind; 
119     for(i = 0; i < 5; i++){ 
120         curkind = (orikind+i)%5; //这块不能写成curkind = (curkind+i)%5;!!!!!注意!!!! 
121         kind = order[color][curkind]; //这里是绝对编号 
122         if(Soldier::life[kind]<=HP) break;
123     } 
124     if(i >= 5){ //已经轮完一轮了,并且这是第一次不能制造新兵 
125         flag = true;
126         if(color) printf("%03d blue headquarter stops making warriors\n",time); //格式化输出 
127         else printf("%03d red headquarter stops making warriors\n",time);
128         return false; 
129     }
130     //成功制造士兵
131     mySoldier[curID]=new Dragon(this, kind, curID);
132     sNum[kind]++;
133     HP-=Soldier::life[kind]; 
134     mySoldier[curID]->Print(time);
135     switch(kind){ //case里不能定义局部变量,除非加作用域符号{} 
136         case 0: 
137             {Dragon d(this, kind, curID); d.Printinfo(); break;} 
138         case 1: 
139             {Ninja n(this, kind, curID); n.Printinfo(); break;} 
140         case 2:
141             {Iceman ii(this, kind, curID); ii.Printinfo(); break;} 
142         case 3: 
143             {Lion l(this, kind, curID); l.Printinfo(); break;} 
144         case 4: break;
145     } 
146     //各种序号要+1
147     curkind = (curkind+1)%5;
148     curID++;
149     return true;
150 }
151 
152 Command::~Command(){
153    for(int i=0;i<curID;i++)
154         delete mySoldier[i];
155 }
156 
157 int main(){
158     int T, M;
159     Command Blue, Red;
160     scanf("%d", &T);
161     for(int i = 1; i <= T; i++){
162         printf("Case:%d\n",i);
163         scanf("%d",&M);
164         Blue.Init(1,M);
165         Red.Init(0,M);
166         for(int j = 0; j <= 4; j++)
167             scanf("%d", &Soldier::life[j]);
168         int time = 0;
169         while(1){
170             bool flagred = Red.Creat(time);
171             bool flagblue = Blue.Creat(time);
172             time++;
173             if(!flagred&&!flagblue) break;
174         }
175     }    
176     return 0; 
177 }

备注:我没啥好说的……看注释吧。我也不知道我这种写法好不好orz

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!