C++學習 —— 靈活的繼承特性

0、繼承與算法開發

  在以前的筆記中,我展現了來自繼承的威力。繼承這種機制可以大幅度減少編碼量,子類能夠繼承父類全部的變量,方法。利用這種機制,咱們能夠在其餘人工做的基礎上,完成有本身特點的部分。好比咱們要開發icp算法,可是pcl中已經提供了icp類,其中有各類方法,能夠調用完成功能。可是icp是瀑布模型的,對於特定的任務有它的瓶頸,若是須要利用C++實現高性能的icp算法,則能夠繼承已有的代碼,開發咱們本身的子流程。ios

 

  上面那一段聽起來頗有道理,其實否則。coding的終極目標並非減小編碼量,而是須要有清晰的架構可讀性,好的擴展性,而且耐造。繼承一部分代碼確實是很偷懶的作法,可是很難保證子類能夠用到父類全部的方法,也就更無從談起父類是子類的抽象了。這對之後的工做留下了隱患,無心義的方法存在對象中,會對後續的繼任者形成困擾。因此若是不是架構清晰,目標明確,最好是不要這樣繼承了。代碼應該扁平化!!!算法

 

一、什麼時候使用繼承

  繼承除了剛剛提到的偷懶之外,它被髮明出來固然有更艱鉅的任務。實現這個艱鉅任務還依賴一個很靈活的特性,稱爲多態。多態纔是真正的大殺器。多態是指,在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便可。可是。。。雖然這個特性很靈活很強大,但是對於科研來講。。。做用實在有限,可能我只在意個人方法,而沒有那麼多其餘方法能夠實現。繼承最大的做用仍是加強程序的可擴展性,或者說增長程序支持的方法。ide

 

  對 C++瞭解的越多,愈加以爲,它適合的是軟件工程,是架構超大規模,面向大量不一樣客戶的大系統。而不是用來實現一個功能,或者一個簡單的算法。繼承是爲了大軟件服務,泛型是爲了大型庫服務.........愈加以爲C++不是玩具,而是生產工具。函數

 

二、一個簡單的多態例子

  仍是那個魔獸世界的問題,如今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
相關文章
相關標籤/搜索