模板,仿函数,函数指针.

#include <iostream>
#include <algorithm>
#include <vector>

//后期 还要 补上 lamba bind function 在 stl中的使用方式。这样对比就很清晰了 。 //不同的需求.找出变化点.进行抽象. //if(*beginit>_value) if(*beginit==_value) .可以用函数指针来完成先抽象工作. //明显抽离出变化后,扩展起来更健壮,因为遍历的代码被复用了.也就不容易出错. //当然也可以用虚函数来完成抽象工作. //可以看出,继承的虚方法在这里并没有体现优势.反而因为虚方法的虚函数表带来的性能差,更重要的是代码更多! //彻底解决了查询需求吗? //如果有个需求是:查找范围在9到10之间,第一个大于9的数字.我们之前的方案,就做不到.bigger 可能会找到11.但我们的预期是没有结果. //这个时候虚函数的便利和抽象的作用就体现出来了. //而单参数的函数指针,根本不存在任何扩展性. //仔细想一下,虚函数是类的函数.而类的基本作用之一就是把数据和方法结合起来. //所以用类的继承实现的需函数,可以通过扩展解决任何的查询需求. //再总结一下,函数指针可以实现抽象,但是函数原型是固定的,参数类型和数量是固定的,只能满足一类需求.(当然可以定义足够多的参数,来实现各种需求,但是脑袋肯定很大..想象一下元素不是int,而是一个复杂类) //而类的继承中的虚函数方案,可以把数据放入派生类中,而基类只提供意图(虚函数).我们之前的虚方法virtual bool CheckLogic(int IteratorItem,int CheckValue)=0; //并没有针对多参数进行彻底抽象,应该virtual bool CheckLogic(int IteratorItem)=0; 彻底吧实现和意图分开.实现所需要的数据放入派生类. //而int IteratorItem 是必须在基类的,回看 MyFind_VirtualFun,这个函数遍历时,会传给我们迭代元素的值.对于我们的虚函数是一个输入参数.没有办法从MyFind_VirtualFun外部传入. //而其他参数,如int CheckValue,是可以在MyFind_VirtualFun外部,传入. //完全好了吧.差不多了. //但是我们再次回头看下,现在为了扩展,导致代码变多了很多.不过也是没有办法的事情.反正新增查询逻辑的时候,还是很方便.写一个继承类就好. //所以,个人认为不管模式,框架本身多复杂,只要稳健,并且带来的是扩展的时候,只需简单代码的话.那么基础代码多点无所谓,反正是一次性模式化的付出.只要是模块化,大概就是好东西.就代表稳定,可复制. //但是还有可改进的地方.仔细观察的话.可以发现. //vector<int>::iterator MyFind_PureVirtualFun(const vector<int>::iterator& start, const vector<int>::iterator& end,VirtualLogic_pure* _mylogic) // if(_mylogic->CheckLogic(*beginit)) //传入的是一个基类的指针,内部指向是基类指针的方法.而有一个东西叫做,仿函数. //如果我们使用防函数 如: if(_mylogic(*beginit)) .那么隐隐约约,有点像函数指针了. //再进一步,如果使用模板呢.哇...那不是在带有数据的类带来的扩展性的基础上,又兼容了函数指针的快捷性? //哦.还不止啊,模板的话,本身就是代码生成器.就有模拟多态的特性.连基类都不用写了. //...无语了,偶然的一次实验,加深了.防函数,模板,和函数指针之间的特性联系的理解. //防函数,行为向一个函数,fun(x), 也就可以说行为像一个函数指针了. pfun(x) //而模板是一个超级代码生成器,只要模板参数行为一致,就可以用同一个模板.所以模板吧防函数和函数指针,完美的兼容起来了. //其中函数指针带有及其便利性.而防函数又带有数据成员,可以进行扩展.所以模板和防函数的存在,把便利和扩展兼得.完美! //最后发现其实STL中的算法find_if .应该和这里的模板方式是一样的. //template<typename T> //vector<int>::iterator MyFind_TemplateFun(const vector<int>::iterator& start, const vector<int>::iterator& end,T _mylogic) //防函数和函数指针在MyFind_TemplateFun直接放入,也可以直接在 find_if上使用. //又意识了,根本不一定要使用函数指针,直接用函数啊,模板是代码生成器....看来还是经验不够. //但是弯路又让我意识到了,模板代码膨胀的一个避免手段:如果频繁使用原型一致的函数作为模板的参数.那么必须使用函数指针作为参数.这样代码就只有一份. //而付出的代码仅仅是,多一条函数指针申明和定义. //同样,如果频繁使用某个模板类,参数是一个放函数.那么定义一个基类,代码也只有一份.


//*可以说标准算法可以看做模板进行了回调.
//而模板的特性给回调添加了新的含义,不仅是函数,防函数也是可以的.

//继续大概看了bind和function。仅仅通过一次实验,基本掌握了bind和function的使用原理。之前大概看了下。不得要领。呵呵。无意中就了解了实质。
//基本都是围绕泛型算法。普通算法需要回调,而回调一般采用函数指针,如果是模板的类的回调。那么支持函数,函数指针,防函数,等一切可以调用的。
//而算法固定为一元或二元参数,为了复用通用函数,作用在算法上,产生了bind(本质产生放函数,其他非固定参数是放函数的成员变量),而lambad基本也是
产生放函数。
//而function.是一个具有函数指针的模板类,可以把所有可调用对象,的调用地址提取出来。那么所有不同类型的可调用对象。就可以放入到一个容器中了。
//function 具体几个方法 if(fun) 来判断fun是否已经赋值,应该是判断指针是否为0, fun.target来获得方法的地址。

using namespace std; //sample fun vector<int>::iterator MyFind_Equare(const vector<int>::iterator& start, const vector<int>::iterator& end,int _value); vector<int>::iterator MyFind_Bigger_first(const vector<int>::iterator& start, const vector<int>::iterator& end,int _value); //pointer fun. typedef bool(* PCheckLogic)(int IteratorItem,int CheckValue); bool Logic_Equare(int IteratorItem,int CheckValue); bool Logic_Bigger(int IteratorItem,int CheckValue); vector<int>::iterator MyFind_PointerFun(const vector<int>::iterator& start, const vector<int>::iterator& end,int _value,PCheckLogic _mylogic); //virtual fun. class VirtualLogic { public: virtual bool CheckLogic(int IteratorItem,int CheckValue)=0; }; class Class_Logic_Equare:public VirtualLogic { public: bool CheckLogic(int IteratorItem,int CheckValue) { return IteratorItem==CheckValue; } }; class Class_Logic_Bigger:public VirtualLogic { public: bool CheckLogic(int IteratorItem,int CheckValue) { return IteratorItem>CheckValue; } }; vector<int>::iterator MyFind_VirtualFun(const vector<int>::iterator& start, const vector<int>::iterator& end,int _value,VirtualLogic* _mylogic); //viratal fun with data member. class VirtualLogic_pure { public: virtual bool CheckLogic(int IteratorItem)=0; }; class Class_pureLogic_Equare:public VirtualLogic_pure { public: Class_pureLogic_Equare(int _c):CheckValue(_c){} bool CheckLogic(int IteratorItem) { return IteratorItem==CheckValue; } int CheckValue; }; class Class_pureLogic_Bigger:public VirtualLogic_pure { public: Class_pureLogic_Bigger(int _c):CheckValue(_c){} bool CheckLogic(int IteratorItem) { return IteratorItem>CheckValue; } int CheckValue; }; class Class_purelogic_Range_Bigger:public VirtualLogic_pure { public: Class_purelogic_Range_Bigger(int f,int t,int c):range_from(f),range_to(t),CheckValue(c){} bool CheckLogic(int IteratorItem) { if(IteratorItem>=range_from&&IteratorItem<=range_to) { return IteratorItem>CheckValue; } else { return false; } } int range_from; int range_to; int CheckValue; }; vector<int>::iterator MyFind_PureVirtualFun(const vector<int>::iterator& start, const vector<int>::iterator& end,VirtualLogic_pure* _mylogic); ////template . // ----- 1)overload operator class likefun_Range_Bigger { public: likefun_Range_Bigger(int f,int t,int c):range_from(f),range_to(t),CheckValue(c){} bool operator()(int IteratorItem) { if(IteratorItem>=range_from&&IteratorItem<=range_to) { return IteratorItem>CheckValue; } else { return false; } } int range_from; int range_to; int CheckValue; }; //-----2)pointor of fun typedef bool(* PCheckLogic_fortemplete)(int IteratorItem); bool range9to10bigger9 (int IteratorItem); template<typename T> vector<int>::iterator MyFind_TemplateFun(const vector<int>::iterator& start, const vector<int>::iterator& end,T _mylogic); int main() { vector<int> intArray; intArray.push_back(1); intArray.push_back(2); intArray.push_back(3); intArray.push_back(5); intArray.push_back(7); intArray.push_back(9); intArray.push_back(11); intArray.push_back(18); cout<<"***********************simple fun****************************"<<endl; vector<int>::iterator ret=MyFind_Equare(intArray.begin(),intArray.end(),4); if(ret!=intArray.end()) { cout<<*ret<<endl; } else { cout<<"can't find it"<<endl; } vector<int>::iterator ret3=MyFind_Bigger_first(intArray.begin(),intArray.end(),9); if(ret3!=intArray.end()) { cout<<*ret3<<endl; } else { cout<<"can't find it"<<endl; } cout<<"***********************pointer fun****************************"<<endl; vector<int>::iterator ret4=MyFind_PointerFun(intArray.begin(),intArray.end(),4,Logic_Equare); if(ret4!=intArray.end()) { cout<<*ret4<<endl; } else { cout<<"can't find it"<<endl; } vector<int>::iterator ret5=MyFind_PointerFun(intArray.begin(),intArray.end(),9,Logic_Bigger); if(ret5!=intArray.end()) { cout<<*ret5<<endl; } else { cout<<"can't find it"<<endl; } //vector<int>::iterator ret99=MyFind_PointerFun(intArray.begin(),intArray.end(),9,0);//空指针造成的问题. cout<<"***********************virtual fun****************************"<<endl; Class_Logic_Equare objEquare=Class_Logic_Equare(); vector<int>::iterator ret6=MyFind_VirtualFun(intArray.begin(),intArray.end(),4,&objEquare); if(ret6!=intArray.end()) { cout<<*ret6<<endl; } else { cout<<"can't find it"<<endl; } Class_Logic_Bigger objBigger=Class_Logic_Bigger(); vector<int>::iterator ret7=MyFind_VirtualFun(intArray.begin(),intArray.end(),9,&objBigger); if(ret7!=intArray.end()) { cout<<*ret7<<endl; } else { cout<<"can't find it"<<endl; } cout<<"***********************virtual fun with memeber data****************************"<<endl; Class_pureLogic_Equare objEquare_pure=Class_pureLogic_Equare(4); vector<int>::iterator ret8=MyFind_PureVirtualFun(intArray.begin(),intArray.end(),&objEquare_pure); if(ret8!=intArray.end()) { cout<<*ret8<<endl; } else { cout<<"can't find it"<<endl; } Class_pureLogic_Bigger objbigger_pure=Class_pureLogic_Bigger(9); vector<int>::iterator ret9=MyFind_PureVirtualFun(intArray.begin(),intArray.end(),&objbigger_pure); if(ret9!=intArray.end()) { cout<<*ret9<<endl; } else { cout<<"can't find it"<<endl; } Class_purelogic_Range_Bigger obj_range_bigger_p=Class_purelogic_Range_Bigger(9,10,9); vector<int>::iterator ret10=MyFind_PureVirtualFun(intArray.begin(),intArray.end(),&obj_range_bigger_p); if(ret10!=intArray.end()) { cout<<*ret10<<endl; } else { cout<<"can't find it"<<endl; } Class_purelogic_Range_Bigger obj_range_bigger2=Class_purelogic_Range_Bigger(9,11,9); vector<int>::iterator ret11=MyFind_PureVirtualFun(intArray.begin(),intArray.end(),&obj_range_bigger2); if(ret11!=intArray.end()) { cout<<*ret11<<endl; } else { cout<<"can't find it"<<endl; } cout<<"***********************templete for overload operator() and pointor of fun ****************************"<<endl; //想具有扩展性就写成类. likefun_Range_Bigger objlikefun(9,15,9); vector<int>::iterator ret12=MyFind_TemplateFun(intArray.begin(),intArray.end(),objlikefun);//会类型推导,可以不写类型. if(ret12!=intArray.end()) { cout<<*ret12<<endl; } else { cout<<"can't find it"<<endl; } //想快捷实现功能,就直接一个函数指针. vector<int>::iterator ret13=MyFind_TemplateFun(intArray.begin(),intArray.end(),range9to10bigger9);//会类型推导,可以不写类型. if(ret13!=intArray.end()) { cout<<*ret13<<endl; } else { cout<<"can't find it"<<endl; } vector<int>::iterator ret14=find_if(intArray.begin(),intArray.end(),objlikefun); if(ret14!=intArray.end()) { cout<<*ret14<<endl; } else { cout<<"can't find it"<<endl; } vector<int>::iterator ret15=find_if(intArray.begin(),intArray.end(),range9to10bigger9); if(ret15!=intArray.end()) { cout<<*ret15<<endl; } else { cout<<"can't find it"<<endl; } } //simple fun vector<int>::iterator MyFind_Equare(const vector<int>::iterator& start, const vector<int>::iterator& end,int _value) { vector<int>::iterator beginit; for(beginit=start;beginit!=end;++beginit) { if(*beginit==_value) { break; } } return beginit; } vector<int>::iterator MyFind_Bigger_first(const vector<int>::iterator& start, const vector<int>::iterator& end,int _value) { vector<int>::iterator beginit; for(beginit=start;beginit!=end;++beginit) { if(*beginit>_value) { break; } } return beginit; } //pointer fun. vector<int>::iterator MyFind_PointerFun(const vector<int>::iterator& start, const vector<int>::iterator& end,int _value,PCheckLogic _mylogic) { vector<int>::iterator beginit; for(beginit=start;beginit!=end;++beginit) { if(_mylogic(*beginit,_value)) { break; } } return beginit; } bool Logic_Equare(int IteratorItem,int CheckValue) { return IteratorItem==CheckValue; } bool Logic_Bigger(int IteratorItem,int CheckValue) { return IteratorItem>CheckValue; } //virtual fun vector<int>::iterator MyFind_VirtualFun(const vector<int>::iterator& start, const vector<int>::iterator& end,int _value,VirtualLogic* _mylogic) { vector<int>::iterator beginit; for(beginit=start;beginit!=end;++beginit) { if(_mylogic->CheckLogic(*beginit,_value)) { break; } } return beginit; } //virtual fun with member data vector<int>::iterator MyFind_PureVirtualFun(const vector<int>::iterator& start, const vector<int>::iterator& end,VirtualLogic_pure* _mylogic) { vector<int>::iterator beginit; for(beginit=start;beginit!=end;++beginit) { if(_mylogic->CheckLogic(*beginit)) { break; } } return beginit; } //template . template<typename T> vector<int>::iterator MyFind_TemplateFun(const vector<int>::iterator& start, const vector<int>::iterator& end,T _mylogic) { vector<int>::iterator beginit; for(beginit=start;beginit!=end;++beginit) { if(_mylogic(*beginit)) { break; } } return beginit; } bool range9to10bigger9 (int IteratorItem) { if(IteratorItem>=9&&IteratorItem<=10) { return IteratorItem>9; } else { return false; } }
原文地址:https://www.cnblogs.com/lsfv/p/6436377.html