C++学习 —— 灵活的继承特性
2016-07-25 09:18
399 查看
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++了解的越多,越发觉得,它适合的是软件工程,是架构超大规模,面向大量不同客户的大系统。而不是用来实现[b]一个[/b]功能,或者一个简单的算法。继承是为了大软件服务,泛型是为了大型库服务.........越发觉得C++不是玩具,而是生产工具。
2、一个简单的多态例子
还是那个魔兽世界的问题,现在warrior 的不同不仅仅是名字了,而是不同的warrior 有不同的特点。我利用多态 & 工厂模式实现了不同特性的warrior 降生。#include <iostream> #include <vector> #include <string> #include <iomanip> using namespace std; class warrior{ public: warrior(int life_,string name_):life(life_),name(name_){ armList.push_back("sword"); armList.push_back("bomb"); armList.push_back("arrow"); } int getLife() const {return this->life;} string getName() const {return this->name;} virtual int getNum() const = 0; virtual void create(int alllife,int bianhao_) = 0; void CommonBurnPrint(int special_num) const{ cout<<' '<<getName() <<' ' <<bianhao <<" with strength " <<getLife() <<", " <<special_num <<' ' <<getName(); } virtual void selfBurnPrint() const = 0; virtual ~warrior(){} private: static int num; const string name; protected: int bianhao; int life; vector<string> armList; }; class Lion: public warrior{ public: Lion(int life_):warrior(life_,"lion"){} void create(int alllife,int bianhao_) { num++; loyal = alllife; bianhao = bianhao_; } int getNum() const {return num;} int getLoyal()const{return loyal;} void selfBurnPrint() const {cout<<"its loyalty is "<<loyal<<endl;} private: static int num; int loyal; }; class Dragon: public warrior { public: Dragon(int life_):warrior(life_,"dragon"){} void create(int alllife,int bianhao_) { bianhao =bianhao_; num++; morale = float(alllife)/life; arm = armList.at((bianhao)%3); } int getNum() const {return num;} string getArm() const{return arm;} int getMorale() const{return morale;} void selfBurnPrint() const {cout<<"it has a "<<arm<<" and its morale is "<<std::setprecision(3)<<morale<<endl;} private: static int num; float morale; string arm; }; class Ninja:public warrior{ public: Ninja(int life_):warrior(life_,"ninja"){} void create(int alllife,int bianhao_){ num++; bianhao = bianhao_; arm1 = armList.at((bianhao)%3); arm2 = armList.at((bianhao+1)%3); } void selfBurnPrint() const {cout<<"it has a "<<arm1<<" and "<<arm2<<endl;} int getNum() const {return num;} string getArm1() const {return arm1;} string getArm2() const{return arm2;} private: static int num; string arm1; string arm2; }; class Iceman:public warrior{ public: Iceman(int life_):warrior(life_,"iceman"){} void create(int alllife,int bianhao_){ num++; bianhao = bianhao_; arm = armList.at((bianhao)%3); } int getNum() const {return num;} string getArm()const {return arm;} void selfBurnPrint() const {cout<<"it has a "<<arm<<endl;} private: static int num; string arm; }; class Wolf:public warrior{ public: Wolf(int life_):warrior(life_,"wolf"){} int getNum() const {return num;} void create(int alllife,int bianhao_){ num++; bianhao = bianhao_; } void selfBurnPrint() const {} private: static int num; }; int warrior::num = 0; int Lion::num = 0; int Iceman::num = 0; int Dragon::num = 0; int Wolf::num = 0; int Ninja::num = 0; class headquarter{ public: headquarter(const string quarterName_,int ALLLIFE_,vector<int> warriorList_,int * warriorlife_):quarterName(quarterName_), ALLLIFE(ALLLIFE_), warriorList(warriorList_), warriorlifeLists(warriorlife_){} bool warriorBurn(int time); private: inline bool __warriorBurn(int warrior_no); const string quarterName; int ALLLIFE; warrior * Warrior; std::vector<warrior*> warrior_house; std::vector<int> warriorList; int * warriorlifeLists; }; bool headquarter::warriorBurn(int time){ int current = time; cout<< setfill('0') << setw(3) << time<<" "; while(!__warriorBurn(warriorList.at(time%5))) { time++; if(current+5 == time) { cout<<this->quarterName<<" stop making warriors"<<endl; return false; } } return true; } bool headquarter::__warriorBurn(int warrior_no){ int dragonlife = warriorlifeLists[0]; int ninjialife = warriorlifeLists[1]; int icemanlife = warriorlifeLists[2]; int lionlife = warriorlifeLists[3]; int wolflife = warriorlifeLists[4]; switch(warrior_no){ case 1: Warrior = new Dragon(dragonlife); break; case 2: Warrior = new Ninja(ninjialife); break; case 3: Warrior = new Iceman(icemanlife); break; case 4: Warrior = new Lion(lionlife); break; case 5: Warrior = new Wolf(wolflife); break; default: return false; } int totalLife = ALLLIFE; totalLife -= Warrior->getLife(); if(totalLife > 0) { ALLLIFE = totalLife; int bianhao = warrior_house.size()+1; Warrior->create(ALLLIFE,bianhao); cout<<this->quarterName; Warrior->CommonBurnPrint(Warrior->getNum()); cout<<" in " <<this->quarterName <<" headquarter" <<endl; Warrior->selfBurnPrint(); warrior_house.push_back(Warrior); return true; } return false; } int main(int argc, char const *argv[]) { int Case; int alllife,lionlife,ninjialife,dragonlife,wolflife,icemanlife; cin>>Case; cin>>alllife; cin>>dragonlife>>ninjialife>>icemanlife>>lionlife>>wolflife; cout<<"case:"<<Case<<endl; int warriorLife[] = {dragonlife,ninjialife,icemanlife,lionlife,wolflife}; warrior * ninja = new Ninja(ninjialife); /* No.1 for dragon No.2 fir ninja No.3 for iceman No.4 for lion No.5 for wolf */ int dragon_No = 1; int ninja_No = 2; int iceman_No = 3; int lion_No = 4; int wolf_No = 5; std::vector<int> red_list; red_list.push_back(iceman_No); red_list.push_back(lion_No); red_list.push_back(wolf_No); red_list.push_back(ninja_No); red_list.push_back(dragon_No); std::vector<int> blue_list; blue_list.push_back(lion_No); blue_list.push_back(dragon_No); blue_list.push_back(ninja_No); blue_list.push_back(iceman_No); blue_list.push_back(wolf_No); headquarter red("red",alllife,red_list,warriorLife); headquarter blue("blue",alllife,blue_list,warriorLife); int time = 0; bool red_result = true; bool blue_result = true; while(1) { if(red_result) red_result = red.warriorBurn(time); if(blue_result) blue_result = blue.warriorBurn(time); if(red_result || blue_result) { time++; continue; } break; } return 0; }
View Code
相关文章推荐
- POJ 2993 - Emag eht htiw Em Pleh
- 单链表反序原理
- POJ 2686 - Y2K Accounting Bug
- C++中类的静态成员
- C++ 指针
- POJ 2632 - Crashing Robots
- leetcode 刷题题解(c++) 2.Add Two Numbers (链表)
- C语言学生管理系统课程设计
- 如何成为一个牛逼的C/C++程序员?
- 20160724-leetcode-string
- 简单的顺序表c语言实现
- c语言实现简单链表
- 李洪强漫谈iOS开发[C语言-021]-运算符
- C++ Union
- 一起talk C栗子吧(第一百七十七回:C语言实例--字符及字符串输入函数二)
- boost::function与回调函数
- 浅析C++const
- C语言课程设计——学生信息管理系统(BUG挺多,敬请指正)
- C语言排序算法
- C语言排序算法