#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;
}
}