• 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
  • 相关阅读:
    Java内存泄漏分析系列之七:使用MAT的Histogram和Dominator Tree定位溢出源
    Java内存泄漏分析系列之六:JVM Heap Dump(堆转储文件)的生成和MAT的使用
    Java内存泄漏分析系列之五:常见的Thread Dump日志案例分析
    Java内存泄漏分析系列之四:jstack生成的Thread Dump日志线程状态
    Java内存泄漏分析系列之三:jstat命令的使用及VM Thread分析
    Java内存泄漏分析系列之二:jstack生成的Thread Dump日志结构解析
    Java内存泄漏分析系列之一:使用jstack定位线程堆栈信息
    安全框架Shiro
    JDK动态代理与CGLib动态代理
    解读分库分表中间件Sharding-JDBC
  • 原文地址:https://www.cnblogs.com/ironstark/p/5697150.html
Copyright © 2020-2023  润新知