C++学习 —— 灵活的继承特性

0、继承与算法开发

  在之前的笔记中,我展示了来自继承的威力。继承这种机制能够大幅度减小编码量,子类可以继承父类所有的变量,方法。利用这种机制,我们可以在其他人工作的基础上,完成有自己特色的部分。比如我们要开发icp算法,但是pcl中已经提供了icp类,其中有各种方法,可以调用完成功能。但是icp是瀑布模型的,对于特定的任务有它的瓶颈,如果需要利用C++实现高性能的icp算法,则可以继承已有的代码,开发我们自己的子流程。

 

  上面那一段听起来很有道理,其实不然。coding的终极目标并不是减少编码量,而是需要有清晰的架构可读性,好的扩展性,并且耐造。继承一部分代码确实是很偷懒的做法,但是很难保证子类可以用到父类所有的方法,也就更无从谈起父类是子类的抽象了。这对以后的工作留下了隐患,无意义的方法存在对象中,会对后续的继任者造成困扰。所以如果不是架构清晰,目标明确,最好是不要这样继承了。代码应该扁平化!!!

 

1、何时使用继承

  继承除了刚刚提到的偷懒以外,它被发明出来当然有更艰巨的任务。实现这个艰巨任务还依赖一个很灵活的特性,称为多态。多态才是真正的大杀器。多态是指,在base类中使用虚函数,而后,以base类指针指向一个derive class object. 那么当我们调用base class 中的虚函数时,指令会前往 derive class 存放函数的空间中,找到对应的实现。比如,base class 是 shape, shape 里面有 cut rotate move draw 方法,但是对于二维图形,三维图形,draw的实现是不一样的。如果在后续的程序中,我们要对shape 进行一系列的操作。而具体是操作二维图形还是三维图形,可能需要在程序运行的时候决定。所以我们可以用基类 shape 的指针来进行后面的工作。此外,shape 指针还可以放在同一个容器中,而两个不同类的指针是没法放在同一个容器里的。

 

  总而言之,继承+多态这种方法,让我们可以在抽象的概念中编写程序。这种特性很灵活,很强大。比如小汽车可以move, 客车也可以 move,挖掘机也可以move。。。。那么我们就只需要对不同的子类实现各自的move,最后决定坐什么车,就调用哪个move即可。但是。。。虽然这个特性很灵活很强大,可是对于科研来说。。。作用实在有限,可能我只在乎我的方法,而没有那么多其他方法可以实现。继承最大的作用还是增强程序的可扩展性,或者说增加程序支持的方法。

 

  对 C++了解的越多,越发觉得,它适合的是软件工程,是架构超大规模,面向大量不同客户的大系统。而不是用来实现一个功能,或者一个简单的算法。继承是为了大软件服务,泛型是为了大型库服务.........越发觉得C++不是玩具,而是生产工具。

 

2、一个简单的多态例子

  还是那个魔兽世界的问题,现在warrior 的不同不仅仅是名字了,而是不同的warrior 有不同的特点。我利用多态 & 工厂模式实现了不同特性的warrior 降生。

 

  1 #include <iostream>
  2 #include <vector>
  3 #include <string>
  4 #include <iomanip>
  5 
  6 using namespace std;
  7 
  8 class warrior{
  9 public:
 10     warrior(int life_,string name_):life(life_),name(name_){
 11         armList.push_back("sword");
 12         armList.push_back("bomb");
 13         armList.push_back("arrow");
 14     }
 15     int getLife()    const {return this->life;}
 16     string getName() const {return this->name;}
 17     virtual int getNum() const  = 0;
 18     virtual void create(int alllife,int bianhao_) = 0;
 19     void CommonBurnPrint(int special_num) const{
 20         cout<<' '<<getName()
 21         <<' '
 22         <<bianhao
 23         <<" with strength "
 24         <<getLife()
 25         <<", "
 26         <<special_num
 27         <<' '
 28         <<getName();
 29     }
 30     virtual void selfBurnPrint() const = 0;
 31 
 32     virtual ~warrior(){}
 33 
 34 private:
 35     static int num;
 36     const  string name;
 37 protected:
 38     int bianhao;
 39     int life;
 40     vector<string> armList;
 41 };
 42 
 43 
 44 class Lion: public warrior{
 45 public:
 46     Lion(int life_):warrior(life_,"lion"){}
 47     void create(int alllife,int bianhao_) {
 48         num++;
 49         loyal = alllife;
 50         bianhao = bianhao_;
 51 
 52     }
 53     int getNum() const {return num;}
 54     int getLoyal()const{return loyal;}
 55     void selfBurnPrint() const {cout<<"its loyalty is "<<loyal<<endl;}
 56 private:
 57     static int num;
 58     int loyal;
 59 };
 60 
 61 class Dragon: public warrior
 62 {
 63 public:
 64     Dragon(int life_):warrior(life_,"dragon"){}
 65     void create(int alllife,int bianhao_) {
 66         bianhao =bianhao_;
 67         num++;
 68         morale = float(alllife)/life;
 69         arm = armList.at((bianhao)%3);
 70 
 71     }
 72     int getNum() const {return num;}
 73     string getArm() const{return arm;}
 74     int    getMorale() const{return morale;}
 75     void selfBurnPrint() const {cout<<"it has a "<<arm<<" and its morale is "<<std::setprecision(3)<<morale<<endl;}
 76 private:
 77     static int num;
 78     float morale;  
 79     string arm;
 80 };
 81 
 82 class Ninja:public warrior{
 83 
 84 public:
 85     Ninja(int life_):warrior(life_,"ninja"){}
 86     void  create(int alllife,int bianhao_){
 87         num++;
 88         bianhao = bianhao_;        
 89         arm1 = armList.at((bianhao)%3);
 90         arm2 = armList.at((bianhao+1)%3);
 91     }
 92     void selfBurnPrint() const {cout<<"it has a "<<arm1<<" and "<<arm2<<endl;}
 93     int getNum() const {return num;}
 94     string getArm1() const {return arm1;}
 95     string getArm2() const{return arm2;}
 96 private:
 97     static int num;
 98     string arm1;
 99     string arm2;
100 };
101 
102 class Iceman:public warrior{
103 public:
104     Iceman(int life_):warrior(life_,"iceman"){}
105     void create(int alllife,int bianhao_){
106         num++;
107         bianhao = bianhao_;
108         arm = armList.at((bianhao)%3);
109     }
110     int getNum() const {return num;}
111     string getArm()const {return arm;}
112     void selfBurnPrint() const {cout<<"it has a "<<arm<<endl;}
113 private:
114     static int num;
115     string arm;
116 };
117 
118 class Wolf:public warrior{
119 public:
120     Wolf(int life_):warrior(life_,"wolf"){}
121     int getNum() const {return num;}
122     void create(int alllife,int bianhao_){
123         num++;
124         bianhao = bianhao_;
125     }
126     void selfBurnPrint() const {}
127 private:
128     static int num;
129 };
130 
131 int warrior::num = 0;
132 int Lion::num   = 0;
133 int Iceman::num = 0;
134 int Dragon::num = 0;
135 int Wolf::num   = 0;
136 int Ninja::num  = 0;
137 
138 class headquarter{
139 public:
140     headquarter(const string quarterName_,int ALLLIFE_,vector<int> warriorList_,int * warriorlife_):quarterName(quarterName_),
141                                                                               ALLLIFE(ALLLIFE_),
142                                                                               warriorList(warriorList_),
143                                                                               warriorlifeLists(warriorlife_){}
144     bool warriorBurn(int time);
145 private:
146     inline bool __warriorBurn(int warrior_no);
147     const string quarterName;
148     int ALLLIFE;
149     warrior * Warrior;
150     std::vector<warrior*> warrior_house;
151     std::vector<int> warriorList;
152     int * warriorlifeLists;
153 };
154 
155 
156 
157 bool headquarter::warriorBurn(int time){
158 
159     int current = time;
160     cout<< setfill('0') << setw(3) << time<<"  ";
161     while(!__warriorBurn(warriorList.at(time%5)))
162     {
163         time++;
164         if(current+5 == time)
165             {
166                 cout<<this->quarterName<<" stop making warriors"<<endl;
167                 return false;
168             }
169     }
170     return true;
171 }
172 
173 
174 bool headquarter::__warriorBurn(int warrior_no){
175     
176     int dragonlife = warriorlifeLists[0];
177     int ninjialife = warriorlifeLists[1];
178     int icemanlife = warriorlifeLists[2];
179     int lionlife   = warriorlifeLists[3];
180     int wolflife   = warriorlifeLists[4];
181 
182 
183     switch(warrior_no){
184         case 1:
185             Warrior = new Dragon(dragonlife);
186             break;
187         case 2:
188             Warrior = new Ninja(ninjialife);
189             break;
190         case 3:
191             Warrior = new Iceman(icemanlife);
192             break;
193         case 4:
194             Warrior = new Lion(lionlife);
195             break;
196         case 5:
197             Warrior = new Wolf(wolflife);
198             break;
199         default:
200             return false;
201     }
202 
203     int totalLife = ALLLIFE;
204     totalLife -= Warrior->getLife();
205     if(totalLife > 0)
206     {
207         ALLLIFE = totalLife; 
208 
209         int bianhao = warrior_house.size()+1;
210         Warrior->create(ALLLIFE,bianhao);        
211         
212         cout<<this->quarterName;
213 
214         Warrior->CommonBurnPrint(Warrior->getNum());
215 
216         cout<<" in "
217         <<this->quarterName
218         <<" headquarter"
219         <<endl;
220 
221         Warrior->selfBurnPrint();
222 
223         warrior_house.push_back(Warrior);
224 
225         return true;
226     }
227     return false;
228 }
229 
230 
231 int main(int argc, char const *argv[])
232 {
233 
234 
235 
236     int Case;
237     int alllife,lionlife,ninjialife,dragonlife,wolflife,icemanlife;
238 
239     cin>>Case;
240     cin>>alllife;
241     cin>>dragonlife>>ninjialife>>icemanlife>>lionlife>>wolflife;    
242     cout<<"case:"<<Case<<endl;
243 
244 
245     int warriorLife[] = {dragonlife,ninjialife,icemanlife,lionlife,wolflife};
246 
247 
248 
249     warrior * ninja = new Ninja(ninjialife);
250     
251 
252 /*  No.1 for dragon
253     No.2 fir ninja
254     No.3 for iceman
255     No.4 for lion
256     No.5 for wolf
257 */
258     int dragon_No = 1;
259     int ninja_No  = 2;
260     int iceman_No = 3;
261     int lion_No   = 4;
262     int wolf_No   = 5;
263 
264     std::vector<int> red_list;
265     red_list.push_back(iceman_No);
266     red_list.push_back(lion_No);
267     red_list.push_back(wolf_No);
268     red_list.push_back(ninja_No);
269     red_list.push_back(dragon_No);
270 
271 
272     std::vector<int> blue_list;
273     blue_list.push_back(lion_No);
274     blue_list.push_back(dragon_No);
275     blue_list.push_back(ninja_No);
276     blue_list.push_back(iceman_No);
277     blue_list.push_back(wolf_No);
278 
279     headquarter red("red",alllife,red_list,warriorLife);
280     headquarter blue("blue",alllife,blue_list,warriorLife);
281 
282     int time = 0;
283     bool red_result = true;
284     bool blue_result = true;
285     while(1)
286     {    
287         if(red_result)
288             red_result = red.warriorBurn(time);
289         if(blue_result)
290             blue_result = blue.warriorBurn(time);
291         if(red_result || blue_result)
292         {
293             time++;
294             continue;
295         }
296         break;
297     }
298    
299     return 0;
300 
301 }
View Code

 

posted @ 2016-07-25 09:18  IronStark  阅读(645)  评论(0编辑  收藏  举报